Search code examples
ruby-on-railsmany-to-manyassociations

About Many-to-Many Associations: id is not saving to database


I'm a beginner in rails and I'm studying Beginning Rails 4 3rd Edition: My rails' version is 4.2.4, Windows 8.1, and Ruby is 2.1.6.

I have 3 models for Rich Many-to-Many Association:

1- Comment

2- Article

3- User

class Comment < ActiveRecord::Base
  belongs_to :article
end

class Article < ActiveRecord::Base
  validates_presence_of :title
  validates_presence_of :body

  belongs_to :user
  has_and_belongs_to_many :categories
  has_many :comments

  def long_title
    "#{title} - #{published_at}"
  end
end

class User < ActiveRecord::Base
  has_one :profile
  has_many :articles, -> {order('published_at DESC, title ASC')},
                      :dependent => :nullify
  has_many :replies, :through => :articles, :source => :comments
end

The issue I want to ask you about is that when I try to create a comment through this association, the comment created comes to have nil id, thus not saved to the database.

For example, I tried the following in the rails console.

article.comments.create(name: 'Amumu', email: '[email protected]', body: 'Amumu is lonely')

And I got the following result.

#<Comment id: nil, article_id: 4, name: "Amumu", email: "[email protected]", body: "Amumu is lonely", created_at: nil, updated_at: nil>

Why does the comment come to have a nil id? I expect it to have a automatically generated id, so saved to the database.


Solution

  • I got to see what my mistake was after considering some of the comments I got here.

    Actually my Comment model was as following.

    class Comment < ActiveRecord::Base
      belongs_to :article
    
      validates_presence_of :name, :email, :body
      validate :article_should_be_published
    
      def article_should_be_published
        errors.add(:article_id, "isn't published yet") if article && !article.published?
      end
    end
    

    Yes, I forgot that I had put a validate method in the Comment model. Because of this validate method, any comment without a value in 'published_at' attribute isn't saved.