Sunday, October 16, 2011

Re: [Rails] Finding the parent of a nested object from it's model before it is saved?

On Mon, Oct 10, 2011 at 1:37 PM, Ewen <ejc7@aecameron.co.uk> wrote:
Is there a way to access a nested objects parent from within that
objects model before it is saved (so I have no ID set yet)?

in artwork.rb:
  has_many artwork_attachment
  accepts_nested_attributes_for :artwork_attachment, :allow_destroy
=> true

artwork_controller.rb's new action includes Artwork.new and
artwork_attachment.build

The problem I have is that in artwork_attachment.rb I have some code
that resets the size of the paperclip attachments based on information
associated with artwork (actually artwork belongs_to line_item which
has_one product and the product has specific dimension). So how can I
refer to the parent of a nested resource before it is actually saved
and gets given an ID?

I faced this problem too.

A solution that seems to work is to explicitly set the relation to the parent
object in the .build method. But I am not sure if this is really kosher ... A
proper solution would be welcome.

A code example:

<code>

class User
  has_many :referrals
  ...
end

class Referral
  belongs_to :user
  ...
end

$ rails c
Loading development environment (Rails 3.1.1.rc1)
001:0> u = User.new(:name => "Frans")
=> #<User id: nil, name: "Frans", created_at: nil, updated_at: nil, age: 0>
002:0> r1 = u.referrals.build(:comment => "dad")
=> #<Referral id: nil, user_id: nil, comment: "dad", created_at: nil, updated_at: nil>
003:0> r2 = u.referrals.build(:comment => "wize", :user => u) ### setting the parent explicitly
=> #<Referral id: nil, user_id: nil, comment: "wize", created_at: nil, updated_at: nil>
004:0> r1.user # I assume this is the "back link" that you are missing
=> nil
005:0> r2.user # and know we can ask the parent before it gets saved and without db query
=> #<User id: nil, name: "Frans", created_at: nil, updated_at: nil, age: 0>
006:0> u.save
   (0.4ms)  BEGIN
  SQL (58.4ms)  INSERT INTO "users" ("age", "created_at", "name", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["age", 0], ["created_at", Sun, 16 Oct 2011 19:39:01 UTC +00:00], ["name", "Frans"], ["updated_at", Sun, 16 Oct 2011 19:39:01 UTC +00:00]]
  SQL (1.1ms)  INSERT INTO "referrals" ("comment", "created_at", "updated_at", "user_id") VALUES ($1, $2, $3, $4) RETURNING "id"  [["comment", "dad"], ["created_at", Sun, 16 Oct 2011 19:39:01 UTC +00:00], ["updated_at", Sun, 16 Oct 2011 19:39:01 UTC +00:00], ["user_id", 5]]
  SQL (0.4ms)  INSERT INTO "referrals" ("comment", "created_at", "updated_at", "user_id") VALUES ($1, $2, $3, $4) RETURNING "id"  [["comment", "wize"], ["created_at", Sun, 16 Oct 2011 19:39:01 UTC +00:00], ["updated_at", Sun, 16 Oct 2011 19:39:01 UTC +00:00], ["user_id", 5]]
   (0.7ms)  COMMIT
=> true
007:0> r1.user # now this works too (based on database id's)
  User Load (1.1ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1
=> #<User id: 5, name: "Frans", created_at: "2011-10-16 19:39:01", updated_at: "2011-10-16 19:39:01", age: 0>
008:0> r2.user # this works too, but does NOT call the database (danger ??)
=> #<User id: 5, name: "Frans", created_at: "2011-10-16 19:39:01", updated_at: "2011-10-16 19:39:01", age: 0>
009:0> r1.user.object_id
=> 85528740
010:0> r2.user.object_id # different object for the parent user
=> 84886560
011:0> r1.user == r2.user # but equivalent user objects
=> true
</code>
 
Specifically in your case, that would probably adding to your artwork_attachments.build
a link to the parent artwork in memory object (before saving to db).

<code>
# I assume the plural artwork_attachments

# in artwork controller
@artwork =   Artwork.new
@artwork.artwork_attachments.build(argument_hash.merge(:artwork => @artwork))

# this then should allow in artwork_attachment.rb 

belongs_to :artwork

dimension = self.artwork.line_item.product.dimension
</code>

I repeat that I am not sure that this is really aproper solution,
and I am curious for the proper solution if it exists.

Thanks,

Peter

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home


Real Estate