Perform the following actions with the following model structure:
tweet=Tweet.create
user=User.new
user.likes.build(tweet_id:tweet.id)
user.save
Then it becomes "Like is invalid" and rolls back.
When building, user_id is nil, so
validates:user_id,presence:true
I think I'm stuck in .
What is the best way to save users and likes simultaneously without changing the model and DB structure?
User Model
has_many:likes
has_many:tweets,through::like
end
Tweet Model
class Tweet <ApplicationRecord
has_many —like
has_many:users,through::like
end
Like Model (Intermediate Table)
class Like <ApplicationRecord
belongs_to —user
belongs_to —Tweet
values:user_id, presence:true
values:tweet_id, presence:true
end
DB
create_table "like", force: :cascade do | t |
t. integer "user_id"
t. integer "tweet_id"
t.datetime "created_at", precision:6, null:false
t.datetime "updated_at", precision:6, null:false
end
create_table "tweets", force: :cascade do | t |
t.string "context"
t.datetime "created_at", precision:6, null:false
t.datetime "updated_at", precision:6, null:false
end
create_table "users", force: :cascade do | t |
t.string "name"
t.datetime "created_at", precision:6, null:false
t.datetime "updated_at", precision:6, null:false
end
tweet=Tweet.create
User.transaction do
user=User.create!
user.likes.create!(tweet_id:tweet.id)
end
If you do so, you can create it without getting stuck in the validation.The point here is the transaction
method, which will save neither User
nor Like
if one of them fails to save the model separately.This seems to meet the actual "concurrent preservation" requirements.
Also, use create!
inside transaction
because this method creates an exception in case of a save failure and rewinds the transaction.Note that create
does not rewind the transaction.
© 2024 OneMinuteCode. All rights reserved.