OrderController#new calls OrderController#current_cart which runs Cart.find(session[:cart_id]). There's no :cart_id at session start, i.e., session[:cart_id] is nil, and you get the Mongoid::Errors::InvalidFind exception above. Note that your rescue clause will not rescue that exception as you are rescuing ActiveRecord::RecordNotFound. You are using Mongoid, not ActiveRecord, and must program accordingly. Best wishes.
Calling Document.find with nil is invalid in mongodb
-
11-10-2022 - |
質問
I am using mongodb with active merchant gem in rails4. While use rails cast tutorial #145 Integrating Active Merchant.
Error
Problem: Calling Document.find with nil is invalid. Summary: Document.find expects the parameters to be 1 or more ids, and will return a single document if 1 id is provided, otherwise an array of documents if multiple ids are provided. Resolution: Most likely this is caused by passing parameters directly through to the find, and the parameter either is not present or the key from which it is accessed is incorrect.
Order Controller
class OrderController < ApplicationController
include ActiveMerchant::Billing::Integrations
def new
@cart = current_cart
@order = Order.new
end
def success
end
def failure
end
def create
@order = current_cart.build_order(params_order)
@order.ip_address = request.remote_ip
if @order.save
if @order.purchase
render :action => "success"
else
render :action => "failure"
end
else
render :action => 'new'
end
end
private
def current_cart
Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
cart = Cart.create
session[:cart_id] = cart.id
cart
end
def params_order
params.require(:order).permit(:first_name, :last_name, :card_type, :card_number, :card_verification, :card_expires_on)
end
end
Model
order.rb
class Order < ActiveRecord::Base
belongs_to :cart
has_many :transactions, :class_name => "OrderTransaction"
attr_accessor :card_number, :card_verification
#validate_on_create :validate_card
def purchase
response = GATEWAY.purchase(price_in_cents, credit_card, purchase_options)
transactions.create!(:action => "purchase", :amount => price_in_cents, :response => response)
cart.update_attribute(:purchased_at, Time.now) if response.success?
response.success?
end
def price_in_cents
return 100 #(cart.total_price*100).round
end
private
def purchase_options
{
:ip => ip_address,
:billing_address => {
:name => "Ryan Bates",
:address1 => "123 Main St.",
:city => "New York",
:state => "NY",
:country => "US",
:zip => "10001"
}
}
end
def validate_card
unless credit_card.valid?
credit_card.errors.full_messages.each do |message|
errors.add_to_base message
end
end
end
def credit_card
@credit_card ||= ActiveMerchant::Billing::CreditCard.new(
:type => card_type,
:number => card_number,
:verification_value => card_verification,
:month => card_expires_on.month,
:year => card_expires_on.year,
:first_name => first_name,
:last_name => last_name
)
end
end
order_transaction.rb
class OrderTransaction
include Mongoid::Document
field :order_id, type: Integer
field :action, type: String
field :amount, type: Integer
field :success, type: Mongoid::Boolean
field :authorization, type: String
field :message, type: String
field :params, type: String
end
cart.rb
class Cart
include Mongoid::Document
has_one :order
end
Route.rb File
get "order/new"
get "order/success"
get "order/failure"
post "order/create", :to => "order#create", as: :orders
resources :cart do
resource :order
end
View
new.html.haml
%br
%br
%h5.text-center
= " Order "
=form_for :order, url:{action: "create"}, html:{class: "form-horizontal"} do |f|
%div.form-group
=f.label :first_name, 'First Name' , {:class => 'col-lg-2 control-label'}
%div.col-lg-3
=f.text_field :first_name, {:class => 'form-control', :placeholder => "First Name"}
%div.form-group
=f.label :last_name, 'Last Name', {:class => 'col-lg-2 control-label'}
%div.col-lg-3
=f.text_field :last_name, {:class => 'form-control', :placeholder => "Last Name"}
%div.form-group
=f.label :card_type, 'Card Type', {:class => 'col-lg-2 control-label'}
%div.col-lg-3
=f.select(:card_type, [["Visa", "visa"], ["MasterCard", "master"], ["Discover", "discover"], ["American Express", "american_express"]], {}, {:class => 'form-control', :placeholder => ""})
%div.form-group
=f.label :card_number, 'Card Number', {:class => 'col-lg-2 control-label'}
%div.col-lg-3
=f.text_field :card_number, {:class => 'form-control', :placeholder => "378282246310005"}
%div.form-group
=f.label :card_verification, 'Card Verification', {:class => 'col-lg-2 control-label'}
%div.col-lg-3
=f.text_field :card_verification, {:class => 'form-control', :placeholder => "YES"}
%div.form-group
=f.label :card_expires_on, 'Card Expire Date', {:class => 'col-lg-2 control-label'}
%div.col-lg-3
=f.date_select :card_expires_on, :discard_day => true, :start_year => Date.today.year, :end_year => (Date.today.year+10), :add_month_numbers => true
%div.form-group
%div.col-lg-offset-2.col-lg-10
=f.submit :class => 'btn btn-primary'
Error Occur
Mongoid::Errors::InvalidFind in OrderController#new Problem: Calling Document.find with nil is invalid. Summary: Document.find expects the parameters to be 1 or more ids, and will return a single document if 1 id is provided, otherwise an array of documents if multiple ids are provided. Resolution: Most likely this is caused by passing parameters directly through to the find, and the parameter either is not present or the key from which it is accessed is incorrect. ** Your suggestion will helpful. Thanks in advanced**
解決