首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >子级可用父模型上的Rails attr_accessor属性

子级可用父模型上的Rails attr_accessor属性
EN

Stack Overflow用户
提问于 2016-02-11 19:06:01
回答 2查看 741关注 0票数 1

上下文:

每个订单都有许多项目&物流。每个项目&物流(以及订单本身)都有很多收入。

我正在创建订单+项目&物流立即使用accepts_nested_attributes_for的订单。但是,收入是通过对每个模型的订单、项目和物流进行after_create回调来创建的。为什么?因为在这些模型中,由于解释上的不同,代码这样读起来更清晰。(但如果这样做是造成这个问题的原因,我显然会重新考虑!)

我需要存储在收入中的一个关键属性是pp_charge_id。但是,无论是订单、商品还是物流,pp_charge_id都不需要担心。我已经附加了一个attr_accessor :pp_charge_id来订购,这样就可以正常工作了,但是,一旦我进入了子项目或物流模型,我就不能再访问pp_charge_id了,我再次需要保存一个相关的收入。我该怎么做?

控制器代码:

代码语言:javascript
运行
复制
@order = Order.new(params) #params includes Order params, and nested params for child Item & Logistics
@order.pp_charge_id = "cash"
@order.save #I need this to not only save the Order, the children Item & Logistics, but then to also create the associated Revenue for each of the aforementioned 3 models

订单模型代码:

代码语言:javascript
运行
复制
has_many :items
has_many :revenues

attr_accessor :pp_charge_id
after_create :create_revenue

def create_revenue
  self.revenues.create(pp_charge_id: self.pp_charge_id)
end

#This WORKS as expected because of the attr_accessor

项目/物流模型代码:

代码语言:javascript
运行
复制
has_many :revenues
belongs_to :order

after_create :create_revenue

def create_revenue
  self.revenues.create(pp_charge_id: self.order.pp_charge_id)
end

 #This DOES NOT work because self.order.pp_charge_id is nil

订单模型代码:

代码语言:javascript
运行
复制
belongs_to :order
belongs_to :item
belongs_to :logistic

同样,我理解attr_accessor的设计并不是为了跨越请求,或者即使订单本身是重新加载的。但是,将它冗余地保存在一个没有使用它的表中也是没有意义的。如果要做到这一点的唯一方法是将pp_charge_id放入订单中,同时保存所有东西(包括收入),那么请告诉我,因为我知道如何做到这一点。(同样,我们宁愿避免这种情况,因为它是如何解释的: params来自用户,收入数据是我提供的)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-11 21:46:57

我认为,如果您希望订单的pp_charge_id应用于其所有项目和物流,我会将所有这些都放入订单的after_create回调中:

代码语言:javascript
运行
复制
# order.rb
def create_revenue
  revenues.create(pp_charge_id: pp_charge_id)
  items.each {|i| i.revenues.create(pp_charge_id: pp_charge_id)}
  logistics.each {|l| l.revenues.create(pp_charge_id: pp_charge_id)}
end

编辑:或者,您可以将inverse_of添加到belongs_to声明中,然后我相信Item#create_revenue会看到在控制器中设置的相同的Order实例。因此,如果还将attr_accessor添加到Item类中,则可以编写其create_revenue,如下所示:

代码语言:javascript
运行
复制
# item.rb
def create_revenue
  revenues.create(pp_charge_id: pp_charge_id || order.pp_charge_id)
end

这应该包括您在评论中提到的新要求。

票数 0
EN

Stack Overflow用户

发布于 2016-02-11 21:24:03

与其使用after_create和访问器,不如考虑使用一种正确的方法来完成所需的任务,即:

代码语言:javascript
运行
复制
Order.create_with_charge(:cash, params)

我发现,仅仅因为代码读起来更干净,在数据库中保持冗余信息就令人不安了!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35347901

复制
相关文章

相似问题

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