使用collection_select并从sqlite3获取意外错误 - 任何人都知道为什么?

时间:2013-05-24 20:33:44

标签: ruby-on-rails ruby ruby-on-rails-3 forms sqlite

我对Ruby on Rails相对较新,使用collection_select时遇到问题并让我的新表单成功提交。关于我的代码的一些背景知识:

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

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

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

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

  4. 我花了一段时间试图弄清楚我做错了什么而没有运气;我无法在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:in create'

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

      { “UTF8”=&gt; “中✓”,  “authenticity_token”=&gt; “中K8 + NnWHIIxVfcC5IvhLhoSKOzuScFrpnHOPTt1pVdpA =”,  “付款”=&GT; { “USER_ID”=&gt; “中new@gmail.com”,  “量”=&gt; “中d”,  “频率”=&gt; “中每两周一次”,  “描述”=&gt; “中ADF”,  “付费”=&gt; “中未决”},  “commit”=&gt;“创建付款”}

1 个答案:

答案 0 :(得分:0)

我已经解决了我的问题。正如我在问题描述中提到的,即使选择了电子邮件地址,我也会通过validates :email, :presence => true收到电子邮件不能为空的错误消息。我找到了this post on Stackoverflow,这让我意识到我希望:email而不是:user_id在表单中提交。

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

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

注意上面的内容也反映了我在视图中构建了一组current_user支付,而不是模型中的实例化变量。