1

語境:Rails的小兒可用父模型attr_accessor屬性

每個訂單有許多項目&物流。每個物品&物流(以及訂單本身)有很多收入。

我正在創建訂單+物品&立即使用訂單上的accepts_nested_attributes_for進行物流。但是,收入是使用after_create回調在每個模型訂單,物料和物流上創建的。爲什麼?因爲鑑於這些模型中解釋的不同,代碼會以這種方式讀取更清晰的內容。 (但是,如果這樣做是因爲什麼導致這個問題被問到,我顯然會重新考慮!)

我需要在收入中存儲的一個關鍵屬性是pp_charge_id。但是pp_charge_id不是訂單,物品或物流需要擔心的事情。我已將attr_accessor :pp_charge_id附加到訂單中,以便一個人可以正常工作,但是,一旦我在子項目或物流模型中,我不再有權訪問pp_charge_id,這也是我需要保存關聯的收入。我應該怎麼做?

控制器代碼:

@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 

ORDER型號代碼:

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 

ITEM/Logistic模型代碼:

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 

ORDER型號代碼:

belongs_to :order 
belongs_to :item 
belongs_to :logistic 

我再次明白attr_accessor沒有設計跨請求或者即使訂單本身重新加載持續。但是將它冗餘保存在沒有用處的表格中也沒有意義。如果唯一的方法是將pp_charge_id納入訂單參數並一次性保存所有內容(包括收入),那麼請告訴我,因爲我知道如何做到這一點。 (再次,只是避免,因爲它的解釋:params來自用戶,收入數據是我提供的)

回答

0

我覺得如果你要應用到其所有項目和物流訂單的pp_charge_id,我把所有的到訂單的after_create回調:

# 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_accessorItem類,你可以寫它的create_revenue這樣的:

# item.rb 
def create_revenue 
    revenues.create(pp_charge_id: pp_charge_id || order.pp_charge_id) 
end 

這應包括您在您的評論中提到了新的要求。

+0

這是唯一的方法嗎?我應該提到的另一件事是,有時候我會像現在的父親一樣在''order.items.create(pp_charge_id:「」))''上創建一個子對象,在這種情況下,我將直接傳入'pp_charge_id'並希望對子項目使用'after_create'回調。 (這也提醒我需要在子項目上使用'attr_accessor:pp_charge_id') – james

+0

@james我添加了一個應該滿足兩種方法的替代方案。 –

+0

'inverse_of'工作!這很奇怪,但我認爲這可能是答案,但後來我看了一遍,看到Rails 4 auto會推斷'inverse_of'。在這種情況下猜測,魔術沒有得到它 – james

0

而不是使用after_create和accessor你應該考慮有一個正確的方法,你需要,即:

Order.create_with_charge(:cash, params) 

我覺得很難將冗餘信息保留在數據庫中,只是因爲代碼讀取更清潔的方式!

+0

這很公平,但在您的自定義方法中,您如何將第一個「現金」參數傳遞給在子項目/物流模型上創建的收入? – james