find_or_create_by rolls back

27 views
Skip to first unread message

fugee ohu

unread,
Feb 1, 2018, 2:30:07 AM2/1/18
to Ruby on Rails: Talk
I'm having find_or_create_by roll back on me in the console directly from the model I'm not providing an id, the mysql id column is autoincrement
Model.find_or_create_by(person_id: 1, picture_id:37)

Message has been deleted

fugee ohu

unread,
Feb 1, 2018, 2:53:06 AM2/1/18
to Ruby on Rails: Talk


On Thursday, February 1, 2018 at 2:30:07 AM UTC-5, fugee ohu wrote:
I'm having find_or_create_by roll back on me in the console directly from the model I'm not providing an id, the mysql id column is autoincrement
Model.find_or_create_by(person_id: 1, picture_id:37)


Forgot to mention Model belongs_to 4 other models

Colin Law

unread,
Feb 1, 2018, 3:51:37 AM2/1/18
to Ruby on Rails: Talk
On 1 February 2018 at 07:30, fugee ohu <fuge...@gmail.com> wrote:
I'm having find_or_create_by roll back on me in the console directly from the model I'm not providing an id, the mysql id column is autoincrement
Model.find_or_create_by(person_id: 1, picture_id:37)

What happens if you try and create a record (where there is not already a matching record) with only those fields?

Colin
 

fugee ohu

unread,
Feb 1, 2018, 8:49:17 AM2/1/18
to Ruby on Rails: Talk
Same thing It works only if I remove all the belongs_to from Model 

Colin Law

unread,
Feb 1, 2018, 8:54:56 AM2/1/18
to Ruby on Rails: Talk
Have you got any validations on the model?
Can you show us the model code where it has the associations and validations?

What do you see in the log when you try to do it?

Colin
 

--
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/aa095ea1-5568-402a-978f-9c6f794a8eb6%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

fugee ohu

unread,
Feb 1, 2018, 9:05:06 AM2/1/18
to Ruby on Rails: Talk


On Thursday, February 1, 2018 at 8:54:56 AM UTC-5, Colin Law wrote:
On 1 February 2018 at 13:49, fugee ohu <fuge...@gmail.com> wrote:


On Thursday, February 1, 2018 at 3:51:37 AM UTC-5, Colin Law wrote:
On 1 February 2018 at 07:30, fugee ohu <fuge...@gmail.com> wrote:
I'm having find_or_create_by roll back on me in the console directly from the model I'm not providing an id, the mysql id column is autoincrement
Model.find_or_create_by(person_id: 1, picture_id:37)

What happens if you try and create a record (where there is not already a matching record) with only those fields?

Colin
 

Same thing It works only if I remove all the belongs_to from Model 

Have you got any validations on the model?
Can you show us the model code where it has the associations and validations?

What do you see in the log when you try to do it?

Colin
 

--
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.


class Relationship < ApplicationRecord
  belongs_to  :picture
  belongs_to  :person
  belongs_to  :address
  belongs_to  :car
end


class Person < ApplicationRecord
 has_many :real_estate_transactions
 has_many :relationships
 has_many :pictures, through: :relationships
 has_many :addresses, through: :relationships
 has_many :cars, through: :relationships
 attr_accessor :address_id
 attr_accessor  :person_id
 attr_accessor  :car_id
 attr_accessor  :picture_id
 def formatted_name
  "#{last_name}, #{first_name}, #{middle_name}, #{name}"
 end

end

class Picture < ApplicationRecord
 validates :name, presence: true
 has_many :relationships
 has_many :people, through: :relationships
 has_many :cars, through: :relationships
 mount_uploader :name, PictureUploader
 attr_accessor  :person_id
 attr_accessor  :car_id
 attr_accessor  :picture_id
  
 def formatted_name
  "#{name}, #{id}"
 end

end

rails c
2.3.3 :001 > Relationship.find_or_create_by(person_id: 1, picture_id: 10)
  Relationship Load (144.3ms)  SELECT  `relationships`.* FROM `relationships` WHERE `relationships`.`person_id` = 1 AND `relationships`.`picture_id` = 10 LIMIT 1
   (1.1ms)  BEGIN
  Picture Load (27.0ms)  SELECT  `pictures`.* FROM `pictures` WHERE `pictures`.`id` = 10 LIMIT 1
  Person Load (5.0ms)  SELECT  `people`.* FROM `people` WHERE `people`.`id` = 1 LIMIT 1
   (25.6ms)  ROLLBACK
 => #<Relationship id: nil, person_id: 1, address_id: nil, real_estate_transaction_id: nil, car_id: nil, event_id: nil, picture_id: 10> 
2.3.3 :002 > 
 

Rob Biedenharn

unread,
Feb 1, 2018, 10:53:43 AM2/1/18
to rubyonra...@googlegroups.com
Does your database have foreign keys set up for these?

Look at the end of your `db/schema.rb` file for lines like:

  add_foreign_key "relationships", "pictures"
  add_foreign_key "relationships", "people"
  add_foreign_key "relationships", "addresses"
  add_foreign_key "relationships", "cars"

If you don't have Person:1 or Picture:10, then this Relationship can't be created.

If you are actually trying to make Relationship be "generic", then you might try something like:

class Relationship < ApplicationRecord
  belongs_to :person
  belongs_to :thing, polymorphic: true
end

(Not that I'm necessarily recommending you do this as I don't know your requirements.)


class Person < ApplicationRecord
 has_many :real_estate_transactions
 has_many :relationships
 has_many :pictures, through: :relationships
 has_many :addresses, through: :relationships
 has_many :cars, through: :relationships
 attr_accessor :address_id
 attr_accessor  :person_id
 attr_accessor  :car_id
 attr_accessor  :picture_id
 def formatted_name
  "#{last_name}, #{first_name}, #{middle_name}, #{name}"
 end

end

Also, why do you have all those `attr_accessor` for the various _id's? If a Person has many Pictures, then there isn't any _single_ picture_id for a person. ActiveRecord will give you an implicit `picture_ids` based on the `has_many` (though it's not likely that you need that much).

-Rob


class Picture < ApplicationRecord
 validates :name, presence: true
 has_many :relationships
 has_many :people, through: :relationships
 has_many :cars, through: :relationships
 mount_uploader :name, PictureUploader
 attr_accessor  :person_id
 attr_accessor  :car_id
 attr_accessor  :picture_id
  
 def formatted_name
  "#{name}, #{id}"
 end

end

rails c
2.3.3 :001 > Relationship.find_or_create_by(person_id: 1, picture_id: 10)
  Relationship Load (144.3ms)  SELECT  `relationships`.* FROM `relationships` WHERE `relationships`.`person_id` = 1 AND `relationships`.`picture_id` = 10 LIMIT 1
   (1.1ms)  BEGIN
  Picture Load (27.0ms)  SELECT  `pictures`.* FROM `pictures` WHERE `pictures`.`id` = 10 LIMIT 1
  Person Load (5.0ms)  SELECT  `people`.* FROM `people` WHERE `people`.`id` = 1 LIMIT 1
   (25.6ms)  ROLLBACK
 => #<Relationship id: nil, person_id: 1, address_id: nil, real_estate_transaction_id: nil, car_id: nil, event_id: nil, picture_id: 10> 
2.3.3 :002 > 
 

--
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.

Hassan Schroeder

unread,
Feb 1, 2018, 11:16:29 AM2/1/18
to rubyonrails-talk
Aside from what other people have already pointed out --

Model.find_or_create_by! will raise an exception on failure, which

will give you more direct info.

I highly recommend reading the docs.

--
Hassan Schroeder ------------------------ hassan.s...@gmail.com
twitter: @hassan
Consulting Availability : Silicon Valley or remote

fugee ohu

unread,
Feb 2, 2018, 12:24:02 AM2/2/18
to Ruby on Rails: Talk
If you're asking about foreign keys then you're kind of saying the record can be created without pre-existing person_id: 1, picture_id: 10, just I shouldn't be using find_or_create_by and I should do it another way Is that your advice?

fugee ohu

unread,
Feb 2, 2018, 12:32:01 AM2/2/18
to Ruby on Rails: Talk
Thanks Hassan, yes that was very revealing PIcture must exist, Car must exist, Address must exist ... seems like everything in the belongs_to list has to exist? I think I need to do this in a more conventional way than to use the unrelationed find_or_create_by  
Reply all
Reply to author
Forward
0 new messages