G'day伙计们,
我目前正在建立一个测试"拍卖"网站来学习铁路.我已经设置了我的拍卖和用户模型,并且只有经过身份验证的用户才能编辑或删除与他们相关的拍卖.
我遇到的困难是将出价项目与拍卖相关联.
我的模型如下:
class Auction < ActiveRecord::Base belongs_to :creator, :class_name => "User" has_many :bids validates_presence_of :title validates_presence_of :description validates_presence_of :curprice validates_presence_of :finish_time attr_reader :bids def initialize @bids = [] end def add_bid(bid) @bids << bid end end
class Bid < ActiveRecord::Base belongs_to :auction, :class_name => "Auction", :foreign_key => "auction_id" belongs_to :bidder, :class_name => "User", :foreign_key => "bidder_id" validates_presence_of :amount validates_numericality_of :amount @retracted = false end
class User < ActiveRecord::Base has_many :auctions, :foreign_key => "owner_id" has_many :bids, :foreign_key => "owner_id" #auth stuff here end
我正在尝试为竞价添加出价记录,但auction_id根本不会添加到记录中.
<% form_for :bid, :url => {:controller => "auction", :action => "add_bids"} do |f|%>Bid Amount <%= f.text_field :amount %>
<%= submit_tag "Add Bid", :auction_id => @auction %> <% end %>
这连接到以下代码:
def add_bids @bid = current_user.bids.create(params[:bid]) if @bid.save flash[:notice] = "New Bid Added" redirect_to :action => "view_auction", :id => @bid.auction_id end end
我得到的问题是auction_id没有放入bid元素.我已经尝试以HTML格式设置它,但我想我错过了很简单的东西.
我的数据模型,回顾一下
用户既有出价也有拍卖
拍卖有一个用户,并有很多出价
出价有用户并有拍卖
在过去的4个小时里,我一直在努力解决这个问题,而且我开始对这一切感到非常失望.
任何帮助将非常感激!
你并没有完全按照Rails的方式做事,这让你有点混乱.在Rails中成功编码完全是关于约定优于配置.意思是,Rails会猜测你的意思,除非你另有说明.如果猜错了,通常会尝试一些事情.但总的来说,坚持确定性的名字,你会没事的.
你的代码中有很多错误,所以我要清理它并以各种方式发表评论,让你知道什么是错的.
应用程序/模型/ auction.rb
class Auction < ActiveRecord::Base belongs_to :creator, :class_name => "User" has_many :bids # Given the nature of your relationships, you're going to want to add this # to quickly find out who bid on an object. has_many :bidders, :through => :bids validates_presence_of :title validates_presence_of :description validates_presence_of :curprice validates_presence_of :finish_time attr_reader :bids #These two methods are unnecessary. # Also don't override initialize in ActiveRecord. Instead use after_initialize #def initialize Supplied by rails when you do has_many :bids # @bids = [] @bids will be populated by what is picked up from #end the database based on the has_many relationship #def add_bid(bid) Supplied by rails when you do has_many :bids # @bids << bid auction.bids << is a public method after has_many :bids #end end
应用程序/模型/ bid.rb
class Bid < ActiveRecord::Base # :class_name and :foreign_key are ony necessary when rails cannot guess from a # association name. :class_name default is the association singularized and # capitalized. :foreign_key default is association_id belongs_to :auction #, :class_name => "Auction", :foreign_key => "auction_id" # here we need :class_name because Rails is looking for a Bidder class. # also there's an inconsistency. Later user refers to has_many bids with # a foreign_key of owner_id, which one is it? bidder_id or owner_id? # if it's owner_id? you will need the :foreign_key option. belongs_to :bidder, :class_name => "User" #, :foreign_key => "bidder_id" validates_presence_of :amount validates_numericality_of :amount # This will never get called in a useful way. # It really should be done in the migration, setting default # value for bids.retracted to false # @retracted = false end
应用程序/模型/ user.rb
class User < ActiveRecord::Base # This makes sense, because an auction can have many bidders, who are also users. has_many :auctions, :foreign_key => "owner_id" # This doesn't. A bid belongs to a user, there's no need to change the name. # See above note re: owner_id vs. bidder_id has_many :bids, :foreign_key => "owner_id" # You could also use this to quickly get a list of auctions a user has bid on has_many :bid_on_auctions, :through => :bids, :source => :auction ... auth stuff ... end
到目前为止一切都那么好吧?
视图不错,但它缺少出价金额的表单部分.此代码假定您将出价值存储在金额列中.我也随意命名为拍卖/出价
应用程序/视图/拍卖/ bid.html.erb
<% form_for :bid, @auction.bids.new do |f|%> <%= f.label_for :amount %> <%= f.text_field :amount%> <%= submit_tag "Add Bid" %>
由表单生成的params哈希:传递给控制器:
params = { :bid => { :auction_id => @auction.id :amount => value of text_field } }
你编写它时由from生成的params哈希(注意:我猜名字是因为它们被遗漏在发布的代码之外):
params = { :id => @auction_id , :bid => { :amount => value of text_field } }
但是,您的控制器代码是您所有问题的来源,这几乎是完全错误的.我猜这是在拍卖控制器中,这似乎是错误的,因为你正试图创建一个出价.让我们看看为什么:
应用程序/控制器/ auctions_controller.rb
... def add_bids # not bad, but... @bid will only fill in the owner_id/bidder_id. and bid amount. @bid = current_user.bids.create(params[:bid]) # create calls save, so this next line is redundant. It still works though. # because nothing's happening between them to alter the outcome of save. if @bid.save flash[:notice] = "New Bid Added" # you should be using restful routes, this almost works, but is ugly and deprecated. # it doesn't work becasue @bid.auction_id is never set. In fact you never use # the auction_id any where, which was in your params_hash as params[:id] redirect_to :action => "view_auction", :id => @bid.auction_id end end ...
这是你的控制器应该如何工作.首先,这应该在bid_controller中,而不是auctions_controller
应用程序/控制器/ bids_controller.rb
... def create @bid = Bid.new(params[:bid]) # absorb values from form via params @bid.bidder = current_user # link bid to current_user. @auction = bid.auction based on. # @auction is set, set because we added it to the @bid object the form was based on. if @bid.save flash[:notice] = "New Bid Added" redirect_to @auction #assumes there is a show method in auctions_controller else render "auctions/show" # or what ever you called the above view end end ...
您还需要确保您的routes.rb中有以下内容(除了可能已存在的内容.这几行将为您设置RESTful路由.
配置/ routes.rb中
ActionController::Routing::Routes.draw do |map| ... map.resources :auctions map.resources :bids ... end
在任何情况下,你都不远.看起来你有一个不错的开始,并且可能会从阅读有关rails的书中获益.如果您不理解底层框架,只是盲目地遵循教程对您没有多大帮助.90%的教程都适用于旧版本的rails并且过时了,这没有任何帮助.
很多代码都是旧的做事方式.特别redirect_to :action => "view_auction", :id => @bid.auction_id
和 <% form_for :bid, :url => {:controller => "auction", :action => "add_bids"} do |f|%>
.使用RESTful路由,它们会变成redirect_to @auction
<%form_for @ auction.bid.new do | f | %>`
这是你应该阅读的资源:
ActiveRecord :: Associations:定义has_many,belongs_to,它们的选项以及它们添加的便捷方法.
了解MVC:更好地理解与Rails相关的信息流
RESTful资源:了解资源.
表单助手:深入描述form_for以及上述代码的工作原理.