Search code examples
ruby-on-railssavedestroy

I deleted an object and attempt to save it again but Rails does not allow it


I'm new to Ruby on Rails and when I'm trying to build a simple web app, I stumbled this error:

  • I have 2 models: User and Post
  • User can have many posts I created a user(user1) and a post(post1) associated with that user:
     user1: #<User:0x00007fb82d27d3b8
  id: 1,
  username: "Thao",
  password: nil,
  email: nil,
  age: nil,
  created_at: Mon, 03 Jul 2023 01:13:07.787945000 UTC +00:00,
  updated_at: Mon, 03 Jul 2023 01:13:07.787945000 UTC +00:00,
  phone_number: nil>

    post1: #<Post:0x00007fb82cc2f038
 id: 1,
 content: "hi this is my first post",
 user_id: 1,
 created_at: Mon, 03 Jul 2023 02:18:35.058605000 UTC +00:00,
 updated_at: Mon, 03 Jul 2023 02:18:35.058605000 UTC +00:00>
class User < ApplicationRecord
    validates :username, presence: true, uniqueness: true, length: { in: 2..20 }

    has_many :posts
end

    class Post < ApplicationRecord
  validates :content, presence: true, length: { minimum: 10 }
  validates :user_id, presence: true
  
  belongs_to :user
end
  • Later, I deleted the post with post1.destroy. When I tried to save it again with post1.save, it returned false , though post1.valid? returned true and post1.errors returned an empty array. I tried post1.save! and it just returned Failed to save the record (ActiveRecord::RecordNotSaved). I also did not have any callback methods.

  • Can anyone tell me why this happened ? Thank you very much.


Solution

  • The post1 object has the id's value.

    You use the method .save so the query will be generated is

    UPDATE ... where id = 1 not CREATE ...

    Solution:

    post1.dup.save 
    

    P/S: You should read more about persistence You can try to create an object by .new instead of using deleted object and then save to see the query.

    UPDATE

    in case, you really want to re-create / restore the old object post1

    restore_post1 = post1.dup
    restore_post1.assign_attributes(id: post1.id)
    restore_post1.save