开发者

association id not getting set using accepts_nested_attributes_for and decent_exposure

When I post a form to create a new inquiry with a child comment (in the app, inquiries can have multiple comments), the comment is not getting built. It works when remove the presence validations. So it has to do with the order in which things are built and saved. How to preserve the validations and keep the code clean?

(The following is an example so it may not be exactly runable)

models/inquiry.rb

class Inquiry < ActiveRecord::Base
  has_many :comments
  accepts_nested_attributes_for :comments

models/comment.rb

class Comment < ActiveRecord::Base
  belongs_to :inquiry
  belongs_to :user
  validates_presence_of :user_id, :inquiry_id

controllers/inquiry_controller.rb

expose(:inquiries)
expose(:inquiry)

def new
  inquiry.comments.build :user => current_user
end

def create
  # inquiry.save => false
  # inquiry.valid? => false
  # inquiry.errors => {:"comments.inquiry_id"=>["can't be blank"]}
end
开发者_开发技巧

views/inquiries/new.html.haml

= simple_form_for inquiry do |f|
  = f.simple_fields_for :comments do |c|
    = c.hidden_field :user_id
    = c.input :body, :label => 'Comment'
= f.button :submit

database schema

create_table "inquiries", :force => true do |t|
  t.string   "state"
  t.datetime "created_at"
  t.datetime "updated_at"
end
create_table "comments", :force => true do |t|
  t.integer  "inquiry_id"
  t.integer  "user_id"
  t.text     "body"
  t.datetime "created_at"
  t.datetime "updated_at"
end


Basically, before saving you are also testing the presence of inquiry_id, the return association from comment to inquiry, that cannot be set until the comment is saved. An alternate way to achieve this and still have your validations intact would be the following:

comment = Comment.new({:user => current_user, :body => params[:body]
comment.inquiry = inquiry
comment.save!
inquiry.comments << comment
inquiry.save!

Or an alternate way would be

= simple_form_for inquiry do |f|
  = f.simple_fields_for :comments do |c|
    = c.hidden_field :user_id
    = c.hidden_field :inquiry_id, inquiry.id
    = c.input :body, :label => 'Comment'
= f.button :submit

Basically adding the following line in your comments form

    = c.hidden_field :inquiry_id, inquiry.id
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜