Today we built a rails app that basically works like Google+. A user has friend circles and makes posts which they selectively show to certain friend circles. A user's own news feed is populated by posts that other users have shared with the friend circles to which this user belongs.
The project focus was on making advanced forms: forms for objects that belong to other resources in the database and/or forms that create multiple objects at once. Here's a summary of how to handle different types of associations:
should have a drop-down select input element or radio buttons that allows the user to choose one resource for the object to belong to
each html option tag should have a name attribute such as name="object[option_id]" and a corresponding value (e.g. if a user belongs to one group, name="user[group_id]" value="<%= group.id %>")
the params will come in as a typical key => value pair; need to require this pair in the strong params
should have check boxes for each source item
each input element needs to have empty brackets so that the collection will be passed as a single array
the array format needs to be specified in the strong params as param: []
when the virtual attribute is set on the creation, rails will automatically make the rows in the join table
should have a nested form so that each of the child objects can be created
for each child object, each of the input elements need to have matching keys so they can be nested together
in the controller, the child objects should be built via the association, using the method singular_ids= [ {key1: val1a, key2: val2a}, {key1: val1b, key2: val2b}, ... ]
to extract that array of params, make a helper method for child_params with params#permit and params#require
class Post < ActiveRecord::Base has_many :links end
class Link < ActiveRecord::Base belongs_to :post end
<label>Title <input type="text" name="post[title]" value="<%= @post.title %>"><br> </label> <label>Description<br> <textarea name="post[body]"></textarea> </label><br> <h3>Links</h3> <% @post.links.each do |link| %> <label>Name <input type="text" name="link[<%= link.object_id %>][name]" value="<%= link.name %>"> </label><br> <label>URL <input type="text" name="link[<%= link.object_id %>][url]" value="<%= link.url %>"> </label><br> <br> <% end %>
{ post: { "title" => "Links!"}, link: { "704668193" => { "name" => 'google', "url" => 'http://google.com' }, "749187302" => { "name" => 'facebook', "url" => 'http://facebook.com' } } }
controllers/posts_controller.rb
def link_params params.permit(:link => [:name, :url]) #filters all but name and url for each link .require(:link) #limits the hash to what's inside link .values #gets the values for each .reject { |link| link.values.all?(&:blank?) } #removes blanks end