Search code examples
ruby-on-rails-5ruby-on-rails-5.2ruby-on-rails-6

ActiveRecord_Associationundefined method `reviews' for #<Post::ActiveRecord_Associations_CollectionProxy:>s_CollectionProxy


I have 3 models in my application namely - user, post and comments. They are associated like this

  • A user can have posts
  • A posts belongs to a user
  • A post can have many reviews
  • A review belongs to a user

Posts Model

class Post < ApplicationRecord
  belongs_to :user
  has_many :comments, dependent: :destroy
  validates :title, presence: true
  validates :body, presence: true
end

User Model

class User < ApplicationRecord

  before_create { generate_token(:auth_token) }

  before_save { self.email = email.downcase }

  has_secure_password
  has_many :posts


  validates :name, presence: true
  validates :email, presence: true, uniqueness: true
  validates :password, confirmation: true
  validates :password_confirmation, presence: true, unless: Proc.new { |a| !a.new_record? && a.password.blank? }

  def send_password_reset
    generate_token(:reset_password_token)
    self.reset_password_sent_at = Time.zone.now
    save!
    UserMailer.password_reset(self).deliver
  end


  def generate_token(column)
    begin
      self[column] = SecureRandom.urlsafe_base64
    end while User.exists?(column => self[column])
  end

end

Review Model

class Review < ApplicationRecord
    belongs_to :user
end

User Controller - show method

  def show
    @user = User.find(params[:id])
    @posts = @user.posts
    @reviews = @posts.reviews //This line shows error
  end

I think something is wrong in the way i am associating these models. I want to show comments made on a post with that post. I show from posts users controller....but i when i tried to display comments the same way. I

I had manually gone and made a comment to post in rails console.

Review table from schema

  create_table "reviews", force: :cascade do |t|
    t.string "comment"
    t.string "user_id"
    t.string "post_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

Solution

  • Can see two issues in the code.

    1 - you haven't define the relationship between post and review in review model.

    class Review < ApplicationRecord
      belongs_to :user
      belongs_to :post
    end
    

    2 - you are trying to get reviews out of posts relation. If you want to get all the reviews for a given user. you should probably need

      def show
       @user = User.find(params[:id])
       @posts = @user.posts
       @reviews = @user.reviews
      end
    

    or you may have to load reviews for each post in the view by

     post.reviews