我遇到了困難的情況。Rails 3特別驗證
class Cart < ActiveRecord::Base
has_many :cart_items
accepts_nested_attributes_for :cart_items
end
class CartItem << ActiveRecord::Base
belongs_to :cart
belongs_to :item
def for_friend?
true if self.friend_email?
end
end
Class Item << ActiveRecord::Base
MAXIMUM_ITEMS_PER_USER = 10
has_many :cart_items
end
好的,這是簡單的關聯案例。每個購物車可以有很多cart_items。 但是,我們不能爲一個用戶銷售超過10件商品(換句話說,1個用戶只能購買10件綠色T恤)。此限制由定義:: Item :: MAXIMUM_ITEMS_PER_USER。
驗證的最簡單的情況是每個記錄的驗證:
例如:我們有CartItem對象:
CartItem id: 1, cart_id: 1, item_id: 1, count: 1, friend_email: nil
和CartItem模型中定義的一些驗證:
class CartItem < ActiveRecord::Base
validates :count_per_user
end
def count_per_user
self.errors.add(:base, "ONLY 10 WE CAN") if self.count > Item::MAXIMUM_ITEMS_PER_USER
end
好的,如果有人設置CartItem對象數超過10個,我們會引發錯誤。
但在我的情況下,用戶可以爲朋友購買一些物品。因此,用戶可以在hes Cart中購買CartItems(區別僅在COUNT和friend_email字段中)。
它看起來像這樣:
CartItem id: 1, cart_id: 1, item_id: 1, count: 1, friend_email: nil
CartItem id: 2, cart_id: 1, item_id: 1, count: 2, friend_email: [email protected]
的問題是什麼,我們需要驗證的「數域」的兩個記錄:)
的方法和我找到的是放置在驗證控制器:
# controller method #update
def update
@cart = Cart.find(params[:id])
update_and_validate_count(params)
end
def update_and_validate_count(controller_params)
@cart_items = get_and_update_cart_items_from(controller_params) # just assign new values, but doesn't save any
summ = @cart_items.inject(0) {|result,r| result += r.count}
if summ > Item::MAXIMUM_ITEMS_PER_USER
@cart.errors.add(:base, "WRONG COUNT, ONLY 10 IS POSSIBLE")
else
@cart.update_attributes(controller_params[:cart])
end
end
這是一種不錯的方法來解決這個問題,但是這是很糟糕( 你能給我一些建議也許u必須在這一些EXP?案件?
主要問題是cart.cart_items在模型級別的調用將從數據庫加載對象,而不是從內存:)這對於使用IdentityMap的Rails 3.1來說不是問題,但是在當前我使用rails 3.0.7 :) – vorobey 2011-04-27 21:53:44
還要感謝有關「計數」的信息。我會解決這個問題。 – vorobey 2011-04-27 21:56:07
'cart.cart_items'只會在你真正引用它作爲一個數組時加載這些項目,但是如果你在它上面調用'sum'就可以生成一個查詢。 ActiveRecord可以用這種方式偷偷摸摸。看看你的查詢日誌,你會發現它沒有像你期望的那樣被加載。 – tadman 2011-04-27 22:09:14