On Sep 24, 2:52 pm, Mark James <
m...@bigpond.net.au> wrote:
> > So, question is: How do I validate the presence of associated objects,
> > while still allowing the building of associated objects to an unsaved
> > model?
>
> Christian, this comes up quite often. I'm glad the incorrect
> warning has been removed from the API, but I would dispute the
> validity of that old ticket [the blog post explaining the
> ticket-creator's reasoning is no longer available].
>
> Here's my most recent post on this topic:
http://groups.google.com/group/rubyonrails-talk/msg/3c01e9b320604dc8
Thank you for this, Mark.
I was able to make the association proxy set the target object on
unsaved associations with the following monkey patch:
module ActiveRecord
module Associations
class AssociationProxy
protected
#
# Allow validates_presence_of :target on belongs_to
associations
# before the target has been saved.
def set_belongs_to_association_for(record)
record["#{@reflection.options[:as]}_type"] =
@owner.class.base_class.name.to_s if @reflection.options[:as]
if @owner.new_record?
set_proxy_target_method = "set_#{@reflection.options[:as] ||
@reflection.primary_key_name.chomp('_id')}_target"
record.send(set_proxy_target_method, @owner)
elsif @reflection.options[:as]
record["#{@reflection.options[:as]}_id"] = @
owner.id
else
record[@reflection.primary_key_name] = @
owner.id
end
end
end
end
end
Now I can do:
p = Post.new
=> #<Post id: nil, name: nil, created_at: nil, updated_at: nil>
c = p.comments.build
=> #<Comment id: nil, text: nil, post_id: nil, created_at: nil,
updated_at: nil>
c.valid?
=> true
Now I wonder: Why doesn't ActiveRecord do this by default?
Christian