Regarding validates_associated... Let''s say I have: article belongs_to author But for whatever reason, I want an article to also be written anonymously and therefore not require an author. Then I have: Article: belongs_to :author validates_associated :author But I DON''T have validates_presence_of. What I want to do is validate that an author is valid --if it is specified--. + I want to allow for the case where article.author_id = nil. + I DO NOT want to allow for the case where article.author_id SOME_INVALID_ID During testing, I tried this: article = Article.new article.author_id = nil assert c.valid? (True -- working so far) article.author_id = 5 assert c.valid? (True -- because author 5 is valid) article.author_id = 999 assert c.valid? (True!?! -- shouldn''t be!) So, how can one protect for the case where the associated link doesn''t refer to an existing database row at all? Can someone give me an example of a successful use of validates_associated that is NOT coupled to validates_presence_of? Afterall, it seems quite pointless to have validates_associated if it returns true for an object that isn''t even in the database. Jake -- Posted via http://www.ruby-forum.com/.
Go here, and look at the if option http://api.rubyonrails.com/classes/ActiveRecord/Validations/ClassMethods.html#M000820 -Nick On 6/13/06, Jake Janovetz <jake@janovetz.com> wrote:> > Regarding validates_associated... > > Let''s say I have: > article belongs_to author > But for whatever reason, I want an article to also be written > anonymously and therefore not require an author. Then I have: > > Article: > belongs_to :author > validates_associated :author > > But I DON''T have validates_presence_of. What I want to do is validate > that an author is valid --if it is specified--. > > + I want to allow for the case where article.author_id = nil. > + I DO NOT want to allow for the case where article.author_id > SOME_INVALID_ID > > During testing, I tried this: > article = Article.new > article.author_id = nil > assert c.valid? (True -- working so far) > article.author_id = 5 > assert c.valid? (True -- because author 5 is valid) > article.author_id = 999 > assert c.valid? (True!?! -- shouldn''t be!) > > So, how can one protect for the case where the associated link doesn''t > refer to an existing database row at all? > > Can someone give me an example of a successful use of > validates_associated that is NOT coupled to validates_presence_of? > Afterall, it seems quite pointless to have validates_associated if it > returns true for an object that isn''t even in the database. > > Jake > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060613/ee459a7e/attachment.html
Nick Stuart wrote:> Go here, and look at the if option > http://api.rubyonrails.com/classes/ActiveRecord/Validations/ClassMethods.html#M000820 > > -NickYes, I considered that. Are you suggesting something like: validates_presence_of :article, :if => Proc.new { |c| !c.article_id.nil? } Jake -- Posted via http://www.ruby-forum.com/.
On Tuesday, June 13, 2006, at 9:04 PM, Jake Janovetz wrote:>Regarding validates_associated... > >Let''s say I have: > article belongs_to author >But for whatever reason, I want an article to also be written >anonymously and therefore not require an author. Then I have: > >Article: > belongs_to :author > validates_associated :author > >But I DON''T have validates_presence_of. What I want to do is validate >that an author is valid --if it is specified--. > >+ I want to allow for the case where article.author_id = nil. >+ I DO NOT want to allow for the case where article.author_id >SOME_INVALID_ID > >During testing, I tried this: > article = Article.new > article.author_id = nil > assert c.valid? (True -- working so far) > article.author_id = 5 > assert c.valid? (True -- because author 5 is valid) > article.author_id = 999 > assert c.valid? (True!?! -- shouldn''t be!) > >So, how can one protect for the case where the associated link doesn''t >refer to an existing database row at all? > >Can someone give me an example of a successful use of >validates_associated that is NOT coupled to validates_presence_of? >Afterall, it seems quite pointless to have validates_associated if it >returns true for an object that isn''t even in the database. > > Jake > >-- >Posted via http://www.ruby-forum.com/. >_______________________________________________ >Rails mailing list >Rails@lists.rubyonrails.org >http://lists.rubyonrails.org/mailman/listinfo/railsOddly enough, I just encounted that problem myself. I am in the process of testing a plugin that fixes the behavior of validates_associated so that it detects invalid entries.. Here it is... should work in most cases, but I haven''t completely tested it. YMMV. from the console, script/generate plugin validates_associated put this in the lib folder and then add require ''validates_associated'' in the init.rb file. Restart your server and you''re off. module ActiveRecord module Validations module ClassMethods # Checks associated object to ensure validity according to ActiveRecord standards # Will not fail if the association is not defined, use validates_presence_of to ensure # a foreign key exists, if necessary. This validation will fail if an associated object is invalid # or if a foreign key points to a non-existent record. def validates_associated(*attr_names) configuration = { :message => ActiveRecord::Errors.default_error_messages[:invalid], :on => :save } configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) validates_each(attr_names, configuration) do |record, attr_name, value| reflection = self.reflect_on_association(attr_name) if reflection.macro == :belongs_to class_to_check = reflection.options[:polymorphic] ? record.send(reflection.options[:foreign_type]).constantize : reflection.active_record unless record.send(reflection.primary_key_name).blank? && class_to_check.exists?(record.send(reflection.primary_key_name)) record.errors.add(attr_name,configuration[:message]) end end record.errors.add(attr_name, configuration[:message]) unless (value.is_a?(Array) ? value : [value]).all? { |r| r.nil? or r.valid? } end end end end end _Kevin -- Posted with http://DevLists.com. Sign up and save your mailbox.
Kevin Olbrich wrote:> Oddly enough, I just encounted that problem myself. I am in the process > of testing a plugin that fixes the behavior of validates_associated so > that it detects invalid entries.. > > Here it is... should work in most cases, but I haven''t completely tested > it. YMMV.Thanks Kevin. I may use the plugin. Really, it was a safety measure -- afterall, my "invalid entries" should have been deleted with proper has_many and belongs_to setups. And other things are wrong if it gets to this point. I''m still curious -- was the original behavior to be expected? Was this how Rails was designed? If so, is there a reason for it? Jake -- Posted via http://www.ruby-forum.com/.
On Tuesday, June 13, 2006, at 10:28 PM, Jake Janovetz wrote:>Kevin Olbrich wrote: >> Oddly enough, I just encounted that problem myself. I am in the process >> of testing a plugin that fixes the behavior of validates_associated so >> that it detects invalid entries.. >> >> Here it is... should work in most cases, but I haven''t completely tested >> it. YMMV. > >Thanks Kevin. I may use the plugin. Really, it was a safety measure -- >afterall, my "invalid entries" should have been deleted with proper >has_many and belongs_to setups. And other things are wrong if it gets >to this point. > >I''m still curious -- was the original behavior to be expected? Was this >how Rails was designed? If so, is there a reason for it? > > Jake > >-- >Posted via http://www.ruby-forum.com/. >_______________________________________________ >Rails mailing list >Rails@lists.rubyonrails.org >http://lists.rubyonrails.org/mailman/listinfo/railsIncidentally, here''s the ticket I opened on this recently. http://dev.rubyonrails.org/ticket/5369 The original behavior is to flag an association as invalid IF and ONLY IF the associated object is invalid (via activerecord). If there is no associated record, it is not flagged as invalid. If the foreign key is invalid, it won''t trigger either. My personal spin on this is that the association should be invalid IF the associated record is invalid AND if the association link is invalid. In most cases, it won''t be an issue because active record is pretty good at cleaning up after itself, but you never know. This is kind of a belt-and-suspenders type of patch. It''s more likely to show up as a problem during development than in live code. _Kevin -- Posted with http://DevLists.com. Sign up and save your mailbox.
Kevin Olbrich wrote:> My personal spin on this is that the association should be invalid IF > the associated record is invalid AND if the association link is invalid. > > In most cases, it won''t be an issue because active record is pretty good > at cleaning up after itself, but you never know. This is kind of a > belt-and-suspenders type of patch. It''s more likely to show up as a > problem during development than in live code. > > _KevinYes. I completely agree. -- Posted via http://www.ruby-forum.com/.