Ruby on Rails Sunday, February 4, 2018



On Sunday, February 4, 2018 at 6:25:46 PM UTC-5, Walter Lee Davis wrote:
Even more interesting (to me, anyway) is what happens if you create (but don't save) any of these objects:

2.4.2 :006 > p = Person.new name: 'Walter'
 => #<Person id: nil, name: "Walter", created_at: nil, updated_at: nil>
2.4.2 :007 > c = Picture.new file: 'some file'
 => #<Picture id: nil, file: "some file", created_at: nil, updated_at: nil>
2.4.2 :008 > p.pictures << c
 => #<ActiveRecord::Associations::CollectionProxy [#<Picture id: nil, file: "some file", created_at: nil, updated_at: nil>]>
2.4.2 :009 > p.save
   (1.9ms)  begin transaction
  SQL (23.1ms)  INSERT INTO "people" ("name", "created_at", "updated_at") VALUES (?, ?, ?)  [["name", "Walter"], ["created_at", "2018-02-04 23:23:15.342294"], ["updated_at", "2018-02-04 23:23:15.342294"]]
  SQL (0.3ms)  INSERT INTO "pictures" ("file", "created_at", "updated_at") VALUES (?, ?, ?)  [["file", "some file"], ["created_at", "2018-02-04 23:23:15.374862"], ["updated_at", "2018-02-04 23:23:15.374862"]]
  SQL (0.4ms)  INSERT INTO "person_pictures" ("person_id", "picture_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["person_id", 2], ["picture_id", 2], ["created_at", "2018-02-04 23:23:15.376805"], ["updated_at", "2018-02-04 23:23:15.376805"]]
   (1.3ms)  commit transaction
 => true
2.4.2 :010 >

When you save one of them, all three are saved in order to preserve the entire set of relationships.

Walter

> On Feb 4, 2018, at 4:54 PM, Walter Lee Davis <wa...@wdstudio.com> wrote:
>
> I can't duplicate this finding here. Here's the console log:
>
> 2.4.2 :001 > p = Person.new name: 'Walter'
> => #<Person id: nil, name: "Walter", created_at: nil, updated_at: nil>
> 2.4.2 :002 > p.save
>   (0.2ms)  begin transaction
>  SQL (2.8ms)  INSERT INTO "people" ("name", "created_at", "updated_at") VALUES (?, ?, ?)  [["name", "Walter"], ["created_at", "2018-02-04 21:47:31.000973"], ["updated_at", "2018-02-04 21:47:31.000973"]]
>   (1.3ms)  commit transaction
> => true
> 2.4.2 :003 > c = Picture.new file: 'some file'
> => #<Picture id: nil, file: "some file", created_at: nil, updated_at: nil>
> 2.4.2 :004 > c.save
>   (0.2ms)  begin transaction
>  SQL (2.2ms)  INSERT INTO "pictures" ("file", "created_at", "updated_at") VALUES (?, ?, ?)  [["file", "some file"], ["created_at", "2018-02-04 21:47:54.717609"], ["updated_at", "2018-02-04 21:47:54.717609"]]
>   (1.4ms)  commit transaction
> => true
> 2.4.2 :005 > p.pictures << c
>   (0.1ms)  begin transaction
>  SQL (0.6ms)  INSERT INTO "person_pictures" ("person_id", "picture_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["person_id", 1], ["picture_id", 1], ["created_at", "2018-02-04 21:47:58.847298"], ["updated_at", "2018-02-04 21:47:58.847298"]]
>   (1.1ms)  commit transaction
>  Picture Load (0.4ms)  SELECT  "pictures".* FROM "pictures" INNER JOIN "person_pictures" ON "pictures"."id" = "person_pictures"."picture_id" WHERE "person_pictures"."person_id" = ? LIMIT ?  [["person_id", 1], ["LIMIT", 11]]
> => #<ActiveRecord::Associations::CollectionProxy [#<Picture id: 1, file: "some file", created_at: "2018-02-04 21:47:54", updated_at: "2018-02-04 21:47:54">]>
> 2.4.2 :006 >
>
> Here's the models:
>
> class Picture < ApplicationRecord
>  has_many :person_pictures
>  has_many :people, through: :person_pictures
> end
>
> class Person < ApplicationRecord
>  has_many :person_pictures
>  has_many :pictures, through: :person_pictures
> end
>
> class PersonPicture < ApplicationRecord
>  belongs_to :person
>  belongs_to :picture
> end
>
> Whatever is happening on your app is not clear, but you can see that after you save the person and the picture, when you add that saved picture to the saved person's 'pictures' collection, the only record that gets created is a person_picture. Now if either the person or the picture was in the "new" state, that is to say, not saved yet, then I could imagine that it would be saved by ActiveRecord first in order to allow the person_picture record to be saved. Both IDs have to be known before the join object can be saved.
>
> Walter
>
>> On Feb 4, 2018, at 2:30 PM, fugee ohu <fuge...@gmail.com> wrote:
>>
>> In a has_many_through association where both records exist how do I create a new association
>> In this case Person has_many_pictures through person_picture and I'm trying to add an existing picture to an existing person like this:
>> @person.pictures << @picture
>> But this creates a new picture instead of adding the association
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
>> To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
>> To post to this group, send email to rubyonra...@googlegroups.com.
>> To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/741e9a16-483f-4fc6-a2e7-77706b9b250c%40googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/EDF36112-47D8-4749-B974-F55A2C57DBA6%40wdstudio.com.
> For more options, visit https://groups.google.com/d/optout.

 
So if @person.pictures << @picture adds a picture to a person, how do you remove a picture from a person?

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe@googlegroups.com.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/9fe3c483-ec8b-42e5-8692-f9db5bf1c907%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment