find_or_create_by rolls back

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

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

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

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 >

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.

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.

class Relationship < ApplicationRecord

belongs_to :picture

belongs_to :person

belongs_to :address

belongs_to :car

end

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

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.

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?

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