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**
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.
Related
When calling GetExpressCheckoutDetails the SHIPTONAME and EMAIL fields are missing from the response. I know that SHIPTONAME is deprecated, but the replacement field is missing as well. Full response below.
I can adjust for the missing name, but need the email for customer communications.
What would cause these fields to be missing from the response?
array(
'TOKEN' => 'XXXXXX',
'BILLINGAGREEMENTACCEPTEDSTATUS' => '0',
'CHECKOUTSTATUS' => 'PaymentActionCompleted',
'TIMESTAMP' => '2015-08-12T16:36:24Z',
'CORRELATIONID' => 'XXXXXX',
'ACK' => 'Success',
'VERSION' => '113',
'BUILD' => '000000',
'PAYERID' => 'XXXXXXXX',
'PAYERSTATUS' => 'verified',
'COUNTRYCODE' => 'US',
'SHIPTOSTREET' => 'XXXXXX',
'SHIPTOCITY' => 'XXXXXX',
'SHIPTOSTATE' => 'XX',
'SHIPTOZIP' => 'XXXXX',
'SHIPTOCOUNTRYCODE' => 'US',
'SHIPTOCOUNTRYNAME' => 'United States',
'ADDRESSSTATUS' => 'Confirmed',
'CURRENCYCODE' => 'USD',
'AMT' => '27.90',
'SHIPPINGAMT' => '0.00',
'HANDLINGAMT' => '0.00',
'TAXAMT' => '0.00',
'NOTIFYURL' => 'https://xxxxx.xxx/xxx',
'INSURANCEAMT' => '0.00',
'SHIPDISCAMT' => '0.00',
'TRANSACTIONID' => 'XXXXXX',
'PAYMENTREQUEST_0_CURRENCYCODE' => 'USD',
'PAYMENTREQUEST_0_AMT' => '27.90',
'PAYMENTREQUEST_0_SHIPPINGAMT' => '0.00',
'PAYMENTREQUEST_0_HANDLINGAMT' => '0.00',
'PAYMENTREQUEST_0_TAXAMT' => '0.00',
'PAYMENTREQUEST_0_NOTIFYURL' => 'https://xxxxx.xxx/xxx',
'PAYMENTREQUEST_0_INSURANCEAMT' => '0.00',
'PAYMENTREQUEST_0_SHIPDISCAMT' => '0.00',
'PAYMENTREQUEST_0_TRANSACTIONID' => 'XXXXXX',
'PAYMENTREQUEST_0_SHIPTOSTREET' => 'XXXXXX',
'PAYMENTREQUEST_0_SHIPTOCITY' => 'XXXXXX',
'PAYMENTREQUEST_0_SHIPTOSTATE' => 'XX',
'PAYMENTREQUEST_0_SHIPTOZIP' => 'XXXXX',
'PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE' => 'US',
'PAYMENTREQUEST_0_SHIPTOCOUNTRYNAME' => 'United States',
'PAYMENTREQUEST_0_ADDRESSSTATUS' => 'Confirmed',
'PAYMENTREQUESTINFO_0_TRANSACTIONID' => 'XXXXX',
'PAYMENTREQUESTINFO_0_ERRORCODE' => '0'
)
There is an issue open with PayPal regarding this and they have acknowledged it as a bug. We suffer the same problems, once in a while the PayerId and any personal detail fields (email address etc) are omitted.
You need to take the correlation ID field that they would have returned to you from the faulty API call and ask them to investigate / open a ticket. That's the only way to get them to respond positively.
Saying that, this has been going on a while now and it is still not solved. But at least you know it's not just you.
I have this code inside app/admin/products.rb. I have problem with that I can see just one input field at time(the last one listed) or just submit button. Does it could be because of some syntax mistakes ? But there is no any error messages.
ActiveAdmin.register Product do
f.input :name,:label => "Name"
f.input :photo, :as => :file
f.input :category, :collection => #category
f.input :manufacturer, :collection => #manufacturer
f.actions do
f.action :submit, :button_html => { :class => "primary", :disable_with => 'Wait...' }
end
end
end
Product model looks like this
attr_accessible :category_id, :description, :manufacturer_id, :name, :photo
extend FriendlyId
has_attached_file :photo,
:styles => {
:thumb=> "100x100#",
:large => "290x170",
:medium=> "120x120"}
friendly_id :name, use: [:slugged, :history]
belongs_to :manufacturer
belongs_to :category
Your form should be inside the block.
Example
ActiveAdmin.register Post do
form do |f|
f.inputs "Details" do
f.input :title
f.input :published_at, :label => "Publish Post At"
f.input :category
end
f.inputs "Content" do
f.input :body
end
f.actions
end
end
Here is more info
http://activeadmin.info/docs/5-forms.html
As shown in the attached image, I want to combine the Sign In form and the Forgot password form into one form. I am using DEVISE and RoR 3.2.5.
The Sign In form looks like:
= simple_form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => {:class => 'form-horizontal'}) do |f|
.inputs
= f.input :login, :required => false, :autofocus => true, :hint => "Enter either email ID or username"
= f.input :password, :required => false
= f.input :remember_me, :as => :boolean if devise_mapping.rememberable?
.form-actions{ :style => "padding-left: 160px;"}
= f.button :submit, "Sign in", :class => "btn btn-primary"
The Forgot password form looks like:
= simple_form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f|
= f.error_notification
.inputs
= f.input :login, :required => true, :hint => "Enter either email ID or username"
.form-actions{ :style => "padding-left: 160px;"}
= f.button :submit, "Send me reset password instructions", :class => "btn btn-primary"
One way is to create a new controller method that reads the value of the submit button.
Based on that value, you should be able to route between the 2 distinct actions.
Another -and probably more modern and clean- way would be to attach javascipt onclick events on one of the buttons that will ignore the form action and submit to a different route.
Rough example:
<script>
$('#forgot-submit-button').click(function(){
$('#my-form').attr('action','<%= forgot_password_path %>').submit()
});
</script>
Not enough time to test this, so please treat it as an example.
I'm having problems submitting my form now that I've converted from erb to haml in a simple sinatra app.
new.haml
%form{ :action => "/new", :method => "post"}
%fieldset
%ol
%li
%label{:for => "username"} Name:
%input{:type => "text", :username => "name", :class => "text"}
%input{:type => "submit", :value => "Send", :class => "button"}
In my app.rb
get '/new' do
haml :new
end
post '/new' do
radcheck = Radcheck.new(:username => params[:username])
if radcheck.save
redirect '/'
else
"Hello World"
end
end
each time I get the Hello World statement appear. My logs show nothing interesting.
Any ideas? Worked just fine with erb??
This is what I've tested
get '/new' do
haml :new
end
post '/new' do
#radcheck = Radcheck.new(:username => params[:username])
username = params[:username]
if username
username
else
"Hello World"
end
end
and new.haml
%form{ :action => "/new", :method => "post"}
%fieldset
%ol
%li
%label{:for => "username"} Name:
%input{:type => "text", :name => "username", :class => "text"}
%input{:type => "submit", :value => "Send", :class => "button"}
And it works as expected. So for some reason radcheck.save is returning false, but that has nothing to do with haml. (But notice that I have corrected input with :name => "username")
Sinatra 1.2.6 / Haml 3.1.2 and Pony
I am getting "wrong number of arguments error (0 for 1)" which points to
sinatra/base.rb
def haml(template, options={}, locals={})
render :haml, template, options, locals
end
I am sending :html_body => (haml :html_email) to Pony
Any help would be very much appreciated!
M.
Your code seems to work in Sinatra 1.2.6, Haml 3.1.3 and Pony 1.3.
Although I would use haml(:test) instead of (haml :test)
test.rb:
require 'rubygems'
require 'sinatra'
require 'pony'
require 'haml'
set :views, Proc.new { root }
get '/send' do
options = {
:to => 'user#gmail.com',
:from => 'user#gmail.com',
:subject => 'Test',
:body => 'Test Text',
:html_body => (haml :test),
:via => :smtp,
:via_options => {
:address => 'smtp.gmail.com',
:port => 587,
:enable_starttls_auto => true,
:user_name => 'login',
:password => 'password',
:authentication => :plain,
:domain => 'HELO'
}
}
Pony.mail(options)
end
test.haml:
!!!
%html
%head
%meta{ :content => "text/html; charset=utf-8", :"http-equiv" => "Content-Type" }
%title Test
%body
%h1 Test
%p Test content