我遇到了困难的情况。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