mač*_*ček 12 activerecord ruby-on-rails
class Auction
belongs_to :item
belongs_to :user, :foreign_key => :current_winner_id
has_many :auction_bids
end
class User
has_many :auction_bids
end
class AuctionBid
belongs_to :auction
belongs_to :user
end
Run Code Online (Sandbox Code Playgroud)
在页面上显示拍卖,用户输入金额并点击出价.控制器代码可能如下所示:
class MyController
def bid
@ab = AuctionBid.new(params[:auction_bid])
@ab.user = current_user
if @ab.save
render :json => {:response => 'YAY!'}
else
render :json => {:response => 'FAIL!'}
end
end
end
Run Code Online (Sandbox Code Playgroud)
这到目前为止工作得很好!但是,我需要确保其他一些事情发生.
@ab.auction.bid_count 需要增加1.@ab.user.bid_count 需要增加1@ab.auction.current_winner_id 需要设置为 @ab.user_id也就是说,User和Auction与关联AuctionBid为了更新以及需要值的AuctionBid#save返回true.
mač*_*ček 11
这两个基地#保存和基地#销毁进来包裹在一个交易,确保,无论你在做验证或回调将交易的保护盖下发生.因此,您可以使用验证来检查事务所依赖的值,或者可以在回调中引发异常以进行回滚,包括after_*回调.
class AuctionBid < ActiveRecord::Base
belongs_to :auction, :counter_cache => true
belongs_to :user
validate :auction_bidable?
validate :user_can_bid?
validates_presence_of :auction_id
validates_presence_of :user_id
# the real magic!
after_save :update_auction, :update_user
def auction_bidable?
errors.add_to_base("You cannot bid on this auction!") unless auction.bidable?
end
def user_can_bid?
errors.add_to_base("You cannot bid on this auction!") unless user.can_bid?
end
protected
def update_auction
auction.place_bid(user)
auction.save!
end
def update_user
user.place_bid
user.save!
end
end
Run Code Online (Sandbox Code Playgroud)
FrançoisBeausoleil+1.感谢您的:foreign_key建议,但是current_winner_*需要在数据库中缓存列以优化查询.
亚历克斯+1.谢谢你让我开始Model.transaction { ... }.虽然这对我来说并不是一个完整的解决方案,但它肯定有助于我指出正确的方向.
| 归档时间: |
|
| 查看次数: |
6737 次 |
| 最近记录: |