2

我对 Ruby on Rails 比较陌生,并且在使用collection_select和成功提交新表单时遇到问题。我的代码的一些背景:

  • 我有一个用户模型和一个付款模型;一个用户has_many付款和一个付款belongs_to用户。
  • 我正在使用设计管理用户登录,当用户登录时,他们可以通过表单添加新的付款。
  • 我正在使用collection_select生成与当前用户关联的电子邮件地址列表,可以通过表单进行选择。

我有两个问题,我认为这两个问题都源于我对 collection_select 的错误使用:

  1. 当我在表单上选择一个电子邮件地址并提交时,我收到一条错误消息,指出电子邮件地址不能为空,即使我提交了非空白条目也是如此。错误消息是我的付款模型中验证的结果,validates :email, :presence => true

  2. 我暂时注释掉了:email我的付款模型中的验证行,现在收到错误消息:SQLite3::SQLException: cannot start a transaction within a transaction: begin transaction.

我花了一段时间试图弄清楚我在没有运气的情况下做错了什么;我在 Stackoverflow 上的其他帖子中找不到这个问题。我猜这是一个简单的错误,但似乎无法弄清楚。有谁知道我做错了什么?

/app/models/payment.rb

require 'valid_email'

class Payment < ActiveRecord::Base
  include ActiveModel::Validations

  attr_accessible :amount, :description, :email, :frequency, :paid, :user_id
  belongs_to :user

  #validates :email, :presence => true, :email => true (commented out as described above)
  validates :amount, :presence => true, :format => { :with => /^\d+??(?:\.\d{0,2})?$/ }, :numericality => {:greater_than => 0, :less_than => 100000}
  validates :description, :presence => true
end

/app/models/user.rb

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  attr_accessible :email, :password, :password_confirmation, :remember_me
  has_many :payments
end

/app/controllers/payments_controller.rb (只需创建和新建):

class PaymentsController < ApplicationController
  before_filter :authenticate_user!
  def create
    @payment = current_user.payments.new(params[:payment])
    @payment_current_user = current_user.payments.all

    respond_to do |format|
      if @payment.save
        format.html { redirect_to payments_url, :flash => { notice: 'Payment was successfully created.' } }
        format.json { render json: @payment, status: :created, location: @payment }
      else
        format.html { render action: "new" }
        format.json { render json: @payment.errors, status: :unprocessable_entity }
      end
    end
  end
  def new
    @payment = current_user.payments.new

    # get list of current_user's email addresses in form
    @payment_current_user = current_user.payments.all

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @payment }
    end
  end
end

/app/views/payments/_form.html.erb

<%= form_for(@payment) do |f| %>
  <form class="form-horizontal">
    <div class="field">
      <div class="control-group">
        <%= f.label :email, "Lendee's Email", class: "control-label" %><br />
        <div class="controls">

          <%= collection_select :payment, :user_id, @payment_current_user, :email, :email, {:include_blank => "Please select"} %>

        </div>
      </div>
    </div>
    <div class="control-group">
      <div class="actions">
        <div class="controls">  
          <%= f.submit %>
        </div>
      </div>
    </div>
  </form>
<% end %>

完整的错误消息,在我单击提交后出现:

ActiveRecord::StatementInvalid in PaymentsController#create
SQLite3::SQLException: cannot start a transaction within a transaction: begin transaction
  • 与错误关联的应用程序跟踪:

    app/controllers/payments_controller.rb:52:in block in create' app/controllers/payments_controller.rb:51:increate'

  • 与错误相关的请求参数:

    {"utf8"=>"✓", "authenticity_token"=>"K8+NnWHIIxVfcC5IvhLhoSKOzuScFrpnHOPTt1pVdpA=", "payment"=>{"user_id"=>"new@gmail.com", "amount"=>"d", "frequency"=>"biweekly", "description"=>"adf", "paid"=>"Pending"}, "commit"=>"Create Payment"}

4

1 回答 1

0

我已经解决了我的问题。正如我在问题描述中提到的那样,即使选择了电子邮件地址,我也会通过validates :email, :presence => trueEmail can't be blank收到错误消息。我在 Stackoverflow 上找到了这篇文章,它帮助我意识到我期待:email,而不是:user_id,以表格形式提交。

结果,我将代码更改为以下内容:

<%= f.collection_select :email, current_user.payments, :email, :email, {:include_blank => "Please select"} %>

请注意,上面还反映了我在视图中构建了一个 current_user 付款数组,而不是从模型中的实例化变量。

于 2013-05-26T13:43:09.467 回答