【问题标题】:At what level in a model object does ActiveRecord not load associated objectsActiveRecord 在模型对象的哪个级别不加载关联对象
【发布时间】:2012-03-09 20:37:57
【问题描述】:

我有几个模型是多个对象的组合。我基本上手动管理它们以进行保存和更新。但是,当我选择项目时,我无权访问所述项目的相关属性。例如:

class ObjectConnection < ActiveRecord::Base
  def self.get_three_by_location_id location_id
    l=ObjectConnection.find_all_by_location_id(location_id).first(3)
    r=[]
    l.each_with_index do |value, key|
      value[:engine_item]=Item.find(value.engine_id)
      value[:chassis_item]=Item.find(value.chassis_id)
      r << value
    end
    return r
  end
end

以及每个项目:

class Item < ActiveRecord::Base
  has_many :assets, :as => :assetable, :dependent => :destroy

当我使用 ObjectLocation.find_three_by_location_id 时,我无权访问资产,而如果在大多数其他情况下使用 Item.find(id),我可以。

我尝试使用包含,但似乎没有这样做。

谢谢

【问题讨论】:

    标签: ruby-on-rails activerecord ruby-on-rails-3.1


    【解决方案1】:

    听起来最简单的解决方案是向您的 ObjectConnection 模型添加方法以便于访问,如下所示:

    class ObjectConnection < ActiveRecord::Base
    
      def engine
        Engine.find(engine_id)
      end
    
      def chassis
        Chassis.find(chassis_id)
      end
    
      # rest of class omitted...
    

    我不确定您要问什么...如果这不能回答您要问的问题,那么您能否尝试更清楚地了解您要完成的工作? ChassisEngine mdoels 是否应该是与您的 Item 模型的多态关联?

    此外,由于您尝试在模型上动态设置属性,因此您在上面使用的代码将不起作用。失败的不是你对Item.find 的调用,而是你对value[:engine_item]=value[:chassis_item] 的调用失败。如果您想保持该流程,则需要将其修改为类似这样:

    def self.get_three_by_location_id location_id
      l=ObjectConnection.find_all_by_location_id(location_id).first(3)
      r=[]
      l.each_with_index do |obj_conn, key|
        # at this point, obj_conn is an ActiveRecord object class, you can't dynamically set attributes on it at this point
        value = obj_conn.attributes # returns the attributes of the ObjectConnection as a hash where you can then add additional key/value pairs like on the next 2 lines
        value[:engine_item]=Item.find(value.engine_id)
        value[:chassis_item]=Item.find(value.chassis_id)
        r << value
      end
      r
    end
    

    但我仍然认为整个方法似乎没有必要,因为如果您在 ObjectConnection 模型上设置适当的关联,那么您不需要像您一样去尝试手动处理关联'正在尝试在这里做。

    【讨论】:

    • 我试过了,但引擎和底盘都是“物品”,我不能拥有belongs_to :item, :foreign_key =&gt; 'engine_id', belongs_to :item, :foreign_key =&gt; 'chassis_id'。看起来这种关系是has_one,但老实说,如何建模这有点超出我的能力。引擎和底盘不是多态的。现在,is_engine、is_chassis 有状态字段。这部分确实有点难看,但它的建模方式在应用程序的其他部分中运行良好。
    • 在我看来,您最好将Item 设为超类,然后再创建一个单独的EngineChassis 模型,它们是Item 的子类。然后为您的Item 类指定polymorphic 关系(这将渗透到其他类)。 Read some more about polymorphic relationships in ActiveRecord here 在 rails 文档网站上。如果您真的想坚持当前的设置(我不推荐),请阅读我修改后的答案的底部。
    • 您提到的那部分代码工作正常 - 在视图中输出正确的数据。
    • 也许编辑关系确实有意义。但真的不想这样做,因为这是唯一不起作用的部分。宁愿只是在视图中进行 ajax 调用以引入这些资产,也不愿在这一点上使用我们的模型。谢谢你的想法!
    • 如何加载/能够访问视图中的关联资产。我怀疑因为 ObjectConnection 不明确知道这些项目是问题,但我不确定。
    猜你喜欢
    • 2014-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    相关资源
    最近更新 更多