Question

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**

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top