Trouble with accepts_nested_attributes_for on validating foreign key

浪尽此生 提交于 2019-12-20 16:23:33

问题


I am using Ruby on Rails v3.2.2. I would like to solve the issue related to the validation of a foreign key when using accepts_nested_attributes_for and validates_associated RoR methods. That is, I have following model classes:

class Article < ActiveRecord::Base
  has_many :category_associations, :foreign_key => 'category_id'

  accepts_nested_attributes_for :category_associations, :reject_if => lambda { |attributes| attributes[:category_id].blank? }
  validates_associated :category_associations
end

class CategoryAssociation < ActiveRecord::Base
  belongs_to :article, :foreign_key => 'article_id'
  belongs_to :category, :foreign_key => 'category_id'

  validates :article_id, :presence => true
  validates :category_id, :presence => true
end

... and I have following controller actions:

class ArticlesController < ApplicationController
  def new
    @article = Article.new
    5.times { @article.category_associations.build }

    # ...
  end

 def create
   @article = Article.new(params[:article])

   if @article.save
     # ...
   else
     # ...
   end
 end
end

With the above code ("inspired" by the Nested Model Form Part 1 Rails Cast) my intent is to store category associations when creating an article (note: category objects are already present in the database; in my case, I would like just storing-creating category associations). However, when I submit the related form from the related view file, I get the following error (I am logging error messages):

{:"category_associations.article_id"=>["can't be blank"], :category_associations=>["is invalid"]}

Why it happens since validates_associated seems to run the method article.category_association.valid? but only if the article.category_association.article_id is not nil? How can I solve the problem with the presence validation of the article_id foreign key?

However, if I comment out the validates :article_id, :presence => true in the CategoryAssociation model class, it works as expected but it seems to be not a right approach to do not validate foreign keys.


If I comment out the validates_associated :category_associations in the Article model class, I still get the error:

{:"category_associations.article_id"=>["can't be blank"]}

回答1:


Use inverse_of to link the associations and then validate the presence of the associated object, not the presence of the actual foreign key.

Example from the docs:

class Member < ActiveRecord::Base
  has_many :posts, inverse_of: :member
  accepts_nested_attributes_for :posts
end

class Post < ActiveRecord::Base
  belongs_to :member, inverse_of: :posts
  validates_presence_of :member
end



回答2:


Since you have a possible nested form with accepts_nested_attributes_for, therefore in CategoryAssociation you need to make the validation conditional, requiring presence for only for only updates:

validates :article_id, presence: true, on: :update

Aside from Active Record associations, you should have a foreign key constraints at the db level.




回答3:


Validations will run on create or save (as you'd expect), so ask yourself, "at each one of those is there a saved instance being referred to?", because without a save an instance won't have an id as it's the database that assigns the id.


Edit: Like I've said in the comments, if you're going to downvote then leave a comment as to why.



来源:https://stackoverflow.com/questions/13344059/trouble-with-accepts-nested-attributes-for-on-validating-foreign-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!