简体   繁体   中英

Rails: How to multiple associations between two models

I have the following association between Reviews and Users:

协会

Since I'm using Devise, I kept just a single Users table and identify the roles using client or seller columns (boolean).

So as you can imagine, I need to know the user that made the review and the user being "reviewed".

The first question is: Can I make use of references while creating the migration? I manually created these columns like this: t.integer:client_id, foreign_key: true and t.integer:seller_id, foreign_key: true

The second is: How can I specify the relationship in the models? I did like this has_many:reviews, foreign_key: "client_id" and has_many:reviews, foreign_key: "seller_id" but i'm not sure if it's correct.

Here's the full code of migration:

class CreateReviews < ActiveRecord::Migration[6.0]
  def change
    create_table :reviews do |t|
      t.text :description
      t.integer :rating, null: false
      t.integer :client_id, foreign_key: true
      t.integer :seller_id, foreign_key: true

      t.timestamps
    end
  end
end

The User Model:

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  has_many :reviews, foreign_key: "client_id"
  has_many :reviews, foreign_key: "seller_id"
end

and the Review model:

class Review < ApplicationRecord
  belongs_to :user
end

Rails Version: 6.0.3.2 - Ruby Version: 2.6.6

I see what you are trying to achieve.

First thing first, remove foreign_key: true in your CreateReviews migration because it has no effect, you might want to index those two columns by replacing it with index: true .

Then in your User model have two different has_many associations eg

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  has_many :client_reviews, foreign_key: "client_id", class_name: 'Review'
  has_many :seller_reviews, foreign_key: "seller_id", class_name: 'Review'
end

Why two different associations? well because when you have two same associations it will always use the last association hence overriding the first one.

You might want to try it in your console and see the output, for your case if you inspect the query you will see that it is using seller_id column to find reviews if you try something like.

user = User.first
p user.reviews.to_sql

Now refactor your Review model to have something like this

class Review < ApplicationRecord
  belongs_to :client, foreign_key: :client_id, class_name: 'User'
  belongs_to :seller, foreign_key: :seller_id, class_name: 'User'
end

Now you can create client_reviews and seller_reviews and query each one

seller = User.create(name: 'Seller 1)
client = User.create(name: 'Client 1')

seller.seller_reviews.create(description: 'I like your product', client: client)

review = Review.first
p review.client
p review.seller

Hope it helps give the picture of what you can do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM