【问题标题】:How to limit an association collection in rails console with "as_json" Active Record methods?如何使用“as_json”Active Record 方法限制 Rails 控制台中的关联集合?
【发布时间】:2021-10-19 19:09:37
【问题描述】:

我想在 Rails 控制台中显示父实体“Article”的限制集合(4 级),这将是其自身与示例之间的关系:

# article.rb

class Article < ActiveRecord::Base
 belongs_to :parent, :class_name => 'Article', optional: true
 has_many :sub_articles, :class_name => 'Article', :foreign_key => 'parent_id'
end

def as_json(options={})
  super(methods: [:subarticles])
end

其中 as_json (ActiveRecord) 方法被覆盖以显示关系中的递归,例如:

 # rails console
 
  Article.first.as_json
  =>
  id: 1,
    name: "king article"
    created_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
    updated_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
    parent_id: nil
    sub_articles:
    [ Article:0x0000641428defb71
    id: 2,
      name: "pencils article"
      created_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
      updated_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
      parent_id: 1
      sub_articles:
        [ Article:0x0000621438defb71
        id: 3,
        name: "pencil child 1"
        created_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
        updated_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
        parent_id: 2
        sub_articles: [],

这可以进一步扩展,但我想将子文章扩展至 4 级......到这样的程度,如果父亲有一个曾曾孙(sub_articles),它就无法显示

【问题讨论】:

    标签: ruby-on-rails ruby recursion activerecord rubygems


    【解决方案1】:
    # in article.rb
    
    def as_json(options={})
      super(methods: [:limited_hierarchy])
    end
    
    def level_in_hierarchy
      return 0 if parent_id.nil?
      return 1 if parent.parent_id.nil?
      return 2 if parent.parent.parent_id.nil?
      return 3 if parent.parent.parent.parent_id.nil?
      # ... etc
    end
    
    def limited_hierarchy
      return sub_articles if level_in_hierarchy < 4
      []
    end
    

    应该可以,level_in_hierarchy 方法可以重构以提高性能,但为了便于阅读,我将其保留为这种方式。我们只关心level_in_hierarchy是否

    根据应用程序中的文章数量,在创建模型时将 level_in_hierarchy 的值设置为 Article 模型中的属性可能是更好的选择。这将提高性能。

    【讨论】:

    • 很好,正是我要找的,通过父母我可以知道儿子的水平。非常感谢您的宝贵时间:D
    【解决方案2】:

    我认为对 Les Nightingill 的回答稍加调整就可以做到你想要的。 添加attr_accesstor :level_in_hierarchy

    # in article.rb
    attr_accesstor :level_in_hierarchy
    
    def as_json(options={})
      super(methods: [:limited_hierarchy])
    end
    
    def limited_hierarchy
      level_in_hierarchy ||= 0
      if level_in_hierarchy < 4
        sub_articles.each { |sub_a| sub_a.level_in_hierarchy = level_in_hierarchy + 1 }
        sub_articles 
      else
        []
      end
    end
    

    【讨论】:

    • 最后我所做的是采用 Les Nightingill 的答案并根据其代码对其进行重构。如果我可以将这两个选项标记为最有用,我会非常高兴地这样做,因为它也以您自己的方式为我服务,非常感谢您的时间和回答:D
    猜你喜欢
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-14
    • 2014-12-06
    • 1970-01-01
    相关资源
    最近更新 更多