通过跨多个模型的关系定义 has_many

Define has_many through relationship across several models

鉴于这些模型关系,我如何检索所有用户列表,这些列表通过卡车、汽车、自行车等相关

#MODELS

class Car < ApplicationRecord
  belongs_to :user

  has_one  :listing, as: :listable
  has_one  :firm, as: :firmable
  has_one  :seller, as: :sellable
end

class Car < ApplicationRecord
  belongs_to :user

  has_one  :listing, as: :listable
  has_one  :firm, as: :firmable
  has_one  :seller, as: :sellable
end

class Bike < ApplicationRecord
  belongs_to :user

  has_one  :listing, as: :listable
  has_one  :firm, as: :firmable
  has_one  :seller, as: :sellable
end

class Listing < ApplicationRecord
  belongs_to :listable, polymorphic: true
end

class User < ApplicationRecord
  has_one :car, dependent: :destroy
  has_one :truck, dependent: :destroy
  has_one :bike, dependent: :destroy

  # need method to retrieve all the listings, which are associated through several models, Car, Truck, Bike, etc.

end

您是否考虑过向 User 模型添加一种方法来满足您的需求?

class User
  has one :car, dependent: :destroy
  has_one :truck, dependent: :destroy
  has_one :bike, dependent: :destroy

  def all_listings
    [car, truck, bike]
  end
end

也许会抛出一个 compact 来丢弃 nils:

def all_listings
  [car, truck, bike].compact
end

我想你可以这样做:

Listing.where(listable: car).or(Listing.where(listable: bike)).or(Listing.where(listable: truck))

它看起来很难看,总共需要 4 个查询,但我不认为你可以用你的模型做得更好。

也许您也可以让 Listing 也属于 User,虽然不确定您是否可以这样做,但对我来说看起来更干净。

此外,您说 "several models" 从您的代码来看,它看起来太相似了。这看起来很奇怪,也许您可​​以改进该设计并获得更清晰的查询。

我建议你应该尝试干燥概念并使用关注

module Vehical
  extend ActiveSupport::Concern

  included do
    has one :car, dependent: :destroy
    has_one :truck, dependent: :destroy
    has_one :bike, dependent: :destroy
  end

  def list_vehicals
   [
     car, 
     truck,
     bike
   ]
  end 
end

然后在您的用户模型中包含关注

class User < ApplicationRecord
  include Vehical
end

然后你可以像

一样使用它
@user = User.find(user_id) 
@user.list_vehicals