定义作用域的多态关联和连接语法。

问题描述 投票:0回答:1

我正试图在我的多态关联中定义一个引用属性 "状态 "的作用域。

我的现实世界的问题是,我有一些引用特定项目的文章和事件。我将这些内容捕获为 item_references。我的文章和事件可以处于草稿或发布状态。我希望能够在关联(item_referenceable)状态为发布的地方提取item_references。

像这样。

scope :published_resource, -> { where("item_referenceable.published?") }

但这显然是行不通的,因为 item_referenceable 是一个实例方法,我在类的层面上工作。我怀疑我需要在join前面下功夫,但我很难理解如何下功夫。

以下是我代码的相关部分。

模型:

class Article < ApplicationRecord
  has_many :item_references, as: :item_referenceable
  accepts_nested_attributes_for :item_references, allow_destroy: true,
   :reject_if => proc { |att| att[:item_unique_id].blank? }
end

class Event < ApplicationRecord
  has_many :item_references, as: :item_referenceable
  accepts_nested_attributes_for :item_references, allow_destroy: true,
   :reject_if => proc { |att| att[:item_unique_id].blank? }
end

class ItemReference < ApplicationRecord
  belongs_to :item_referenceable, polymorphic: true

  scope :in_articles, -> { where("item_referenceable_type = 'Article'") }
end

Schema Extracts:

create_table "events", id do |t|
t.string "title"
t.datetime "start_date_time"
t.datetime "end_date_time"
t.string "state"

create_table "article", id do |t|
t.string "title"
t.string "slug"
t.text "body"
t.string "state"

create_table "item_references", id do |t|
t.text "item_unique_reference"
t.string "item_referenceable_type"
t.bigint "item_referenceable_id"
t.index ["item_referenceable_type", "item_referenceable_id"], name: "idx_item_refs"

这个问题很可能会扩大,因为我最终会在多个模型中引用项目,比如课程,博客等。我想知道是否有可能在不指定具体模型名称的情况下定义范围,并使用 item_referenceable_type 来引用模型名称。

这是我不成功的尝试。

scope :published_resource, -> { joins(:item_referenceable_type).where('item_references.item_referenceable.published?') }

我最终想生成一个API 通过 item_unique_id 显示所有引用该项目的文章和事件。

像这样。

{
 "title": "Retrieve all item references",
 "items": [
   {
     "item_unique_id": "O12",
     "articles": [
       {
         "resource_id": 1,
         "title": "Penguin",
         "state": "published",
         "slug": "test-article"
       }
      ],
     "events": []
   },

我在上面的阶段使用了 ItemReference.all.group_by(&:item_unique_id) 但它会检索所有资源(EventsArticles),无论它们是否被发布。

ruby-on-rails activerecord polymorphic-associations
1个回答
1
投票

下面是我建议如何处理这个问题:(用简写的方式,因为扩展的功能几乎肯定是一个需求。

class Publishable 
   PUBLISHABLES = {articles: Article, events: Event}
   attr_reader :results
   attr_accessor :limit, :conditions   
   def initialize(conditions={})
      @conditions = conditions 
      @results = {} 
   end   

   def as_json(options={})
     fetch if results.empty?  
     results.as_json(options) 
   end  

   def published!
     conditions.merge!({stage: 'Published'})
     self 
   end 

   private 
     def fetch
       PUBLISHABLES.each do |node, klass| 
         results[node] = klass.where(conditions).limit(limit)
       end  
     end 
end 

那么你可以简单地调用

publishables = Publishable.new
publishables.published!
publishables.limit = 10 
publishables.results 

正如我所提到的,这只是为了给你举个例子,是非常过度简化的,我当然会考虑扩展这个功能,但希望它能帮助你指出一个方向。

© www.soinside.com 2019 - 2024. All rights reserved.