passing params throught rails forms

I am using rails 4 and have a subject and comment models. Subject is a one to many relationship with comments. I want a simple page that can add comments to many subjects on the same page. So in my form I know how to submit a comment to create but I dont know how to find the right subject in my controller to add it to. Any advice?

class CommentsController < ApplicationController
  def create
    comment = Comment.create(comment_params)
    if comment.save
      # The line below is incorrect, I dont know what to do
      Subject.find(params[:subject_id]).comments << comment
      redirect_to(:controller => 'static_pages', action: 'home')
    end
  end

  def new
  end

  private

  def comment_params
      params.require(:comment).permit(:text, :user_name)
  end

end

StaticPages#home

Find me in app/views/static_pages/home.html.erb

<% @subjects.each do |subject| %>
  <div class="subjects <%= cycle('odd', 'even') %>">

  <h1><%= subject.name %></h1>
  <h3><%= subject.description %></h3>

    <% subject.comments.each do |comment|%>
        <div class="comment">
        <h4><%= comment.user_name%></h4>
        <%= comment.text  %>
        </div>
    <% end %>

    <%= form_for(@comment) do |f| %>
        <%= f.label :user_name %>
        <%= f.text_field :user_name %>

        <%= f.label :text %>
        <%= f.text_field :text %>

        <%= f.submit('Create comment', subject_id: subject.id) %>
    <% end %>


  </div>
<% end %>

Upvotes: 1

Views: 38

Answers (1)

Richard Peck
Richard Peck

Reputation: 76784

The simplest way would be to populate the subject_id attribute of your @comment form, like this:

<%= form_for(@comment) do |f| %>
    <%= f.label :user_name %>
    <%= f.text_field :user_name %>

    <%= f.label :text %>
    <%= f.text_field :text %>

    <%= f.hidden_field :subject_id, value: subject.id %>

    <%= f.submit('Create comment', subject_id: subject.id) %>
<% end %>

This will populate the subject_id attribute of your new Comment object, which will essentially associate it through Rails' backend:

enter image description here

#app/controllers/your_controller.rb
Class YourController < ApplicationController
   def create
       @comment = Comment.new comment_params
       @comment.save
   end

   private

   def comment_params
       params.require(:comment).permit(:subject_id, :text, :user_name)
   end
end

--

foreign_keys

This works because of the Rails / relational database foreign_keys structure

Every time you associate two objects with Rails, or another relational database system, you basically have a database column which links the two. This is called a foreign_key, and in your case, every Comment will have the subject_id foreign_key column, associating it with the relevant subject

So you may have many different forms using the same @comment variable - the trick is to populate the foreign_key for each one

Upvotes: 2

Related Questions