Rueian
Rueian

Reputation: 163

rails multiple belongs_to assignments with nested attributes

My problem is that how to assign multiple belongs_to associations with nested attributes?

I want to build a issue system. When I create a issue, I also want to create the first comment as the issue body.

So, I have following Models:

class Issue < ActiveRecord::Base
  has_many :comments, as: :commentable

  validates :title, presence: true

  accepts_nested_attributes_for :comments
end

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :commentable, polymorphic: true

  validates :content, :user, presence: true
end

and I have the IssuesController as follow:

class IssuesController < ApplicationController
  before_action :authenticate_user! #devise authentication

  def new
    @issue = Issue.new
    @issue.comments.build
  end

  def create
    @issue = Issue.new(issue_params)
    @issue.save
  end

  private

  def issue_params
    params.require(:issue).permit(:title, comments_attributes: [:content])
  end
end

and the following is my form (using slim template with simple_form and nested_form gems):

= simple_nested_form_for @issue do |f|

  = f.input :title

  = f.fields_for :comments do |cf|
    = cf.input :content

  = f.button :submit

In this case, I don't know how to assign current_user to the comment created by nested attributes.

Any suggestions or other approaches? Thanks!

Upvotes: 1

Views: 88

Answers (2)

Nermin
Nermin

Reputation: 6100

You could also add user_id as current_user.id when you use params

class IssuesController < ApplicationController
  before_action :authenticate_user! #devise authentication

  def new
    @issue = Issue.new
    @issue.comments.build
  end

  def create
    @issue = Issue.new(issue_params)
    @issue.save
  end

  private

  def issue_params
    params[:issue][:comment][:user_id] = current_user.id
    params.require(:issue).permit(:title, comments_attributes: [:content, :user_id])
  end
end

Upvotes: 0

Noel Frostpaw
Noel Frostpaw

Reputation: 3999

As I wrote in the comments, there's two ways of doing this. The first way is to add a hidden field in your subform to set the current user:

= simple_nested_form_for(@issue) do |f|
  = f.input :title
  = f.fields_for(:comments) do |cf|
    = cf.input(:content)
    = cf.hidden(:user, current_user)
  = f.submit

If you do not trust this approach in fear of your users fiddling with the fields in the browser, you can also do this in your controller.

class IssuesController < ApplicationController
  before_action :authenticate_user! #devise authentication

  def new
    @issue = Issue.new
    @issue.comments.build
  end

  def create
    @issue = Issue.new(issue_params)
    @issue.comments.first.user = current_user
    @issue.save
  end

  private

  def issue_params
    params.require(:issue).permit(:title, comments_attributes: [:content])
  end
end

This way you take the first comment that is created through the form and just manually assign the user to it. Then you know for the sure that the first created comment belongs to your current user.

Upvotes: 1

Related Questions