首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails 5.2多态关联与多态条件

Rails 5.2多态关联与多态条件
EN

Stack Overflow用户
提问于 2019-09-05 03:01:35
回答 2查看 2.9K关注 0票数 1

模型:

代码语言:javascript
复制
class Car < ApplicationRecord
  belongs_to :user

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

class Truck < 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
  has_many :favorites, dependent: :destroy
  has_many :users_who_favorited, through: :favorites, source: :user
end

假设汽车和卡车都有一个user_id字段..。

Listing.includes(:listable)返回一个加载的清单AR关系。

但是,我需要通过user_id过滤,所以我试着.

Listing.includes(:listable).where(user_id: 100)

但我有个错误..。

ActiveRecord::StatementIn有效值(PG::UndefinedColumn: ERROR: listings.user_id列不存在)第1行:从“列表”选择“列表”.*,其中“列表”。

就像它在列表上查找user_id一样。然而,我需要过滤列表表,所以这意味着要么汽车或卡车表。无论可列表定义如何。

我也试过:

Listing.includes(listable:[:user]).where('users.id = 100')

但我得到..。

ActiveRecord::StatementIn有效表(PG::UndefinedTable: ERROR:从表“users”中缺少-子句条目)第1行:从“列表”选择“列表”.*,其中(users.id = 100) .^:从“列表”中选择“列表”.* (users.id = 100)限制$1

更新:

然后试着

代码语言:javascript
复制
class Listing < ApplicationRecord
  belongs_to :listable, polymorphic: true
  has_many :favorites, dependent: :destroy
  has_many :users_who_favorited, through: :favorites, source: :user

  belongs_to :car, -> { includes(:listable).where(listable: { listable_type: Car.to_s }) }, foreign_key: :listable_id
  belongs_to :truck, -> { includes(:listable).where(listable: { listable_type: Truck.to_s }) }, foreign_key: :listable_id

end

试过Listing.includes(:car, :truck)但是..。

ActiveRecord::ConfigurationError (不能将“Car”加入到名为“listable”的关联中;您可能拼写错了吗?)

因此,我不能尝试下面的工作,直到上面的工作。

Listing.includes(:car, :truck).where(cars: { user_id: 1 }).or(Listing.includes(:car, :truck).where(trucks: { user_id: 1 }))

但是,我可以执行Listing.includes(:listable)并且它确实工作,当我添加一个条件时,它会中断。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-09-05 09:28:33

这是我几个月来提出的一个非常有趣的问题。然后我找到了解决办法。

在您的Listing模型中,为了能够包含您的polymorphic模型,您需要告诉您的模型它们是相关的。

代码语言:javascript
复制
class Car < ApplicationRecord
  belongs_to :user

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

class Truck < 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
  has_many :favorites, dependent: :destroy
  has_many :users, through: :favorites

  #magic happens here
  belongs_to :car, -> { includes(:listings).where(listings: { listable_type: Car.to_s }) }, foreign_key: :listable_id
  belongs_to :truck, -> { includes(:listings).where(listings: { listable_type: Truck.to_s }) }, foreign_key: :listable_id

end

现在,您可以简单地做:Listing.includes(:car, :truck),它将完美地工作:-)

就你的情况而言:

代码语言:javascript
复制
Listing.includes(:car, :truck).where(cars: { user_id: 1 }).or(Listing.includes(:car, :truck).where(trucks: { user_id: 1 }))
票数 4
EN

Stack Overflow用户

发布于 2019-09-05 18:56:26

对于那些和我一样难以解决的人.

我的最后解决办法是:

代码语言:javascript
复制
    def left_join_listable(table_name, listable_type_value)
      "LEFT OUTER JOIN \"#{table_name}\" "\
      "ON \"#{table_name}\".\"id\" = \"listings\".\"listable_id\" "\
      "AND \"listings\".\"listable_type\" = #{listable_type_value}"
    end

   def left_join_users_on(*table_names)
      join = "LEFT OUTER JOIN \"users\" ON "
      conditionals = table_names.map {|table_name| "\"users\".\"id\" = \"#{table_name}\".\"user_id\"" }.join(" OR ")
      join + conditionals
    end

Listing.joins(left_join_listable('cars',"\'Car\'"))
       .joins(left_join_listable('trucks',"\'Trucks\'"))
       .joins(left_join_users_on('cars','trucks')
       .where(users.id = (?), 100)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57797880

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档