Rails Associations&Object Identity:通过一系列更改来维护对象身份



`首先,我甚至提出这个问题的事实意味着我有意识地选择不(严格)遵守德米特定律。

由于有时(可能是rails 3?)引用model.association.first每次都会产生一个新对象,除非您在关联上使用.to_a

campaign.campaign_shirts.first.to_s
=> "#<CampaignShirt:0x007fdd02c7fd58>"
campaign.campaign_shirts.first.to_s
=> "#<CampaignShirt:0x007fdd02ca6318>"
c.campaign_shirts.to_a.first.to_s
=> "#<CampaignShirt:0x007fdd02d13170>"
c.campaign_shirts.to_a.first.to_s
=> "#<CampaignShirt:0x007fdd02d13170>"

我在几个Rails 3/4应用程序上工作过,甚至没有注意到这一点,可能是因为我确实尽可能尊重Demeter。

在这种情况下,我希望Campaign处于控制之中,因为它是一个大型状态机,其中许多状态更改都涉及到事务协调自身和各种子对象中的更改。

有没有办法在创建和/或获取时冻结关联数组?

编辑:当你使用Campaign.includes(...).find时,我几乎立刻注意到它们被冻结了,我正在我的应用程序中这样做。然而,在对象是FactoryGirl创建的工厂的规格方面,我仍然有一个问题。有没有办法说"冻结这个对象上的所有关联",或者我必须对每个关联调用.to_a

编辑2:当我通过用户上的belongs_to引用活动时,我仍然有一个问题。(这似乎是一个单独的问题,所以我在这里问了它)。编辑3:belongs_to-includes扩展的问题只是语法,所以我将删除其详细信息。

所以,我剩下的问题是让User.selected_campaign像FactoryGirl构建应用程序时那样运行。我将尝试在每个规范的开头做一个.reload,这应该会触发includes扩展,但要牺牲一些规范性能。

我不知道你的设置的(血腥的)细节,但如果你只是在Campaign对象上存储first呢?

def Campaign
  def first_campaign_shirt
    @first_campaign_shirt ||= campaign_shirts.first
  end
end

我认为这样你又遵守了德米特定律?但是,如果您需要更多的getter而不仅仅是first_shirt,那么这可能会变得很烦人。因此,考虑一下这只是一个不适合放在评论框中的建议。:)

通过仔细选择将includes(..)添加到关联和作用域的位置,我的所有应用内用例都得到了解决。

我只能通过在创建工厂对象后调用reload来解决工厂女孩的问题。

最新更新