I have following controller
class PaypalOrdersController < Spree::BaseController
def new
#paypal_order = PaypalOrder.new
end
def create
#order1 = current_order
#paypal_order = PaypalOrder.new(params[:paypal_order])
if #paypal_order.save
if #paypal_order.purchase
render :action => "success"
else
render :action => "failure"
end
else
render :action => "new"
end
end
end
and the corresponding model is:
class PaypalOrder < ActiveRecord::Base
require 'paypal_payment'
belongs_to :order
attr_accessor :card_number, :card_verification
validate :validate_card, :on => :create
def purchase
orderHash = #order1.clone
paypalHash = #paypal_order.clone
PaypalPayment.new(orderHash, paypalHash)
end
private
def validate_card
#some code
end
def credit_card
#some code
end
end
When the purchase method is triggered I'm getting the error cannot clone nil class. On debugging I found that #order1 and #paypal_order both are nil in the purchase method. I am not sure why this is happening. Please can someone explain.
Thanks
controller:
PaypalOrder.purchase #order1, #paypal_order
model:
def self.purchase order, paypal_order
orderHash = order.clone
paypalHash = paypal_order.clone
PaypalPayment.new(orderHash, paypalHash)
end
edit:
How do you pass data from a controller to a model with Ruby on Rails?
Try this
controller
if #paypal_order.purchase #order1
model
def purchase order1
orderHash = order1.clone
paypalHash = self.clone
PaypalPayment.new(orderHash, paypalHash)
end
Related
I have seen this error, I understand the problem or so I hope I do, the problem being my order_items are saving before an Order Id has been created. The problem of being a nube is having a clue about the problem but not idea about how to implement the solution, your patience is appreciated.
The error I am getting.
ActiveRecord::RecordNotSaved (You cannot call create unless the parent is saved):
app/models/shopping_bag.rb:22:in add_item'
app/controllers/order_items_controller.rb:10:increate'
My OrderItems controller
class OrderItemsController < ApplicationController
def index
#items = current_bag.order.items
end
def create
current_bag.add_item(
book_id: params[:book_id],
quantity: params[:quantity]
)
redirect_to bag_path
end
def destroy
current_bag.remove_item(id: params[:id])
redirect_to bag_path
end
end
My Orders controller
class OrdersController < ApplicationController
before_action :authenticate_user!, except:[:index, :show]
def index
#order = Order.all
end
def new
#order = current_bag.order
end
def create
#order = current_bag.order
if #order.update_attributes(order_params.merge(status: 'open'))
session[:bag_token] = nil
redirect_to root_path
else
render new
end
end
private
def order_params
params.require(:order).permit(:sub_total, :status, :user_id)
end
end
My shopping bag Model
class ShoppingBag
delegate :sub_total, to: :order
def initialize(token:)
#token = token
end
def order
#order ||= Order.find_or_create_by(token: #token, status: 'bag') do | order|
order.sub_total = 0
end
end
def items_count
order.items.sum(:quantity)
end
def add_item(book_id:, quantity: 1)
book = Book.find(book_id)
order_item = order.items.find_or_create_by(
book_id: book_id
)
order_item.price = book.price
order_item.quantity = quantity
ActiveRecord::Base.transaction do
order_item.save
update_sub_total!
end
end
def remove_item(id:)
ActiveRecord::Base.transaction do
order.items.destroy(id)
update_sub_total!
end
end
private
def update_sub_total!
order.sub_total = order.items.sum('quantity * price')
order.save
end
end
Thank you, your time is appreciated.
From docs about find_or_create_by:
This method always returns a record, but if creation was attempted and failed due to validation errors it won’t be persisted, you get what create returns in such situation.
Probably this is the situation - the record was not persisted in a database, but only created in memory. Looking at your code, I think you want to use a bang-version of the method (find_or_create_by!), which will raise an error in such situation.
To use parent attributes in child when using nested_attributes you can use inverse_of. Here is the documentation which may help you understand why parents need to be created first.
UPDATED with example: This will create forums first and then posts.
class Forum < ActiveRecord::Base
has_many :posts, :inverse_of => :forum
end
class Post < ActiveRecord::Base
belongs_to :forum, :inverse_of => :posts
end
I have an "Add To Cart" function working fine based on Sessions so no user is currently logged in.
Here's the Model
class Cart < ActiveRecord::Base
has_many :tutors
def add_tutor(tutor_id)
tutor = Tutor.find(tutor_id)
if tutor
self.tutors << tutor
end
save
end
end
Here's the Controller
class CartsController < ApplicationController
def show
#cart = current_cart
end
def add_to_cart
current_cart.add_tutor(params[:tutor_id])
redirect_to tutors_path
end
end
What i would like to do is when the user checkouts, they will be redirected to a page with a simple form requesting for their name/email/phone-number, and when that email is sent to me, it includes the items in their cart.
I am currently using gem 'mail_form' and this is what i have set-up so far.
Model checkout.rb
class Checkout < MailForm::Base
attribute :name, :validate => true
attribute :email, :validate => /\A([\w\.%\+\-]+)#([\w\-]+\.)+([\w]{2,})\z/i
attribute :hp, :validate => true
def headers
{
:subject => "Tutor Checkout",
:to => "xxx#xxx.com"
}
end
end
Controller checkouts_controller.rb
class CheckoutsController < ApplicationController
def new
#checkout = Checkout.new
end
def create
#checkout = Checkout.new(params[:checkout])
#checkout.request = request
if #checkout.deliver
flash[:notice] = 'Thank you! We will be in touch with you shortly!'
else
flash[:error] = 'There was an error in sending your message!'
render :new
end
end
end
and under views/checkouts/new.html.erb its just a form requesting for their information.
What i really have no idea on where to start is creating the association between Carts and Checkouts and how do i even include the items in the cart to be sent along with the email?
Any help or advice would be greatly appreciated! Thank you!
I am making a basic account setup and to try to learn how the database stuff works. I have been running into this error constantly, and I have no idea how to make it disappear. I have my stuff named as U, so the URL will be easier to type a username like Reddit has it example.com/u/username
The Error is uninitialized constant UController::User_param
It highlights this code: #user = U.new(User_param)
Controller:
class UController < ApplicationController
def index
#users = U.all
end
def show
end
def create
#user = U.new(User_param)
if #user.save
redirect_to :action => 'list'
else
#user = U.all
render :action => 'new'
end
end
def User_param
params.require(:Us).permit(:id, :email, :password, :created_at, :updated_at)
end
def new
#user = U.new
end
def edit
end
end
Routes:
resources :u
U Model:
class U < ActiveRecord::Base
end
In Rails you don't capitalize methods, only constants and classes. change User_param to user_params along with the method and that should work. I made params plural since it is clearer and easier to understand
Also, change the user_param method to this:
def user_params
params.require(:u).permit(:id, :email, :password, :created_at, :updated_at)
end
The .require(:u) doesn't need to be plural as you had it.
UPDATE: I have solved the NilClass issue! Thanks!
Now I am having a problem with:
unknown attribute 'sessionId' for Room.
SOLVEDI am currently having some issues where my code is telling me I have an error of "undefined method `create_session' for nil:NilClass" on line 9. I will provide the files.
This is the specific line:
#new_room = Room.new(strong_param)
rooms_controller.rb
class RoomsController < ApplicationController
require "opentok"
before_filter :config_opentok,:except => [:index]
def index
#rooms = Room.where(:public => true).order("created_at DESC")
#new_room = Room.new
end
def create
session = #opentok.create_session :media_mode => :routed
params[:room][:sessionId] = session.session_id
#new_room = Room.new(strong_param)
respond_to do |format|
if #new_room.save
format.html { redirect_to(“/party/”+#new_room.id.to_s) }
else
format.html { render :controller => ‘rooms’, :action => “index” }
end
end
end
def party
#room = Room.find(params[:id])
#tok_token = #opentok.generate_token #room.sessionId
end
private
def config_opentok
if #opentok.nil?
#opentok = OpenTok::OpenTok.new ########, "#########################################"
end
end
def strong_param
params.require(:room).permit(:name,:sessionId)
end
end
rooms.rb (Models)
class Room < ActiveRecord::Base
end
I've tried several different modifications to these files to make my program work. I can get the listing page to work but once I try and actually create a new room, I receive this error message.
Look forward to any advice you can provide.
You are missing the before_filter :config_opentok,:except => [:index] line from the blog post in your previous post (https://railsfornovice.wordpress.com/2013/01/01/video-chatting-in-ruby-on-rails/)
I am trying to get some information posted using our accountancy package (FreeAgentCentral) using their API via a GEM.
http://github.com/aaronrussell/freeagent_api/
I have the following code to get it working (supposedly):
Kase Controller
def create
#kase = Kase.new(params[:kase])
#company = Company.find(params[:kase][:company_id])
#kase = #company.kases.create!(params[:kase])
respond_to do |format|
if #kase.save
UserMailer.deliver_makeakase("dropbox#12808311.macandco.highrisehq.com", "Highrise", #kase)
#kase.create_freeagent_project(current_user)
#flash[:notice] = 'Case was successfully created.'
flash[:notice] = fading_flash_message("Case was successfully created & sent to Highrise.", 5)
format.html { redirect_to(#kase) }
format.xml { render :xml => #kase, :status => :created, :location => #kase }
else
format.html { render :action => "new" }
format.xml { render :xml => #kase.errors, :status => :unprocessable_entity }
end
end
end
To save you looking through, the important part is:
#kase.create_freeagent_project(current_user)
Kase Model
# FreeAgent API Project Create
# Required attribues
# :contact_id
# :name
# :payment_term_in_days
# :billing_basis # must be 1, 7, 7.5, or 8
# :budget_units # must be Hours, Days, or Monetary
# :status # must be Active or Completed
def create_freeagent_project(current_user)
p = Freeagent::Project.create(
:contact_id => 0,
:name => "#{jobno} - #{highrisesubject}",
:payment_terms_in_days => 5,
:billing_basis => 1,
:budget_units => 'Hours',
:status => 'Active'
)
user = Freeagent::User.find_by_email(current_user.email)
Freeagent::Timeslip.create(
:project_id => p.id,
:user_id => user.id,
:hours => 1,
:new_task => 'Setup',
:dated_on => Time.now
)
end
lib/freeagent_api.rb
require 'rubygems'
gem 'activeresource', '< 3.0.0.beta1'
require 'active_resource'
module Freeagent
class << self
def authenticate(options)
Base.authenticate(options)
end
end
class Error < StandardError; end
class Base < ActiveResource::Base
def self.authenticate(options)
self.site = "https://#{options[:domain]}"
self.user = options[:username]
self.password = options[:password]
end
end
# Company
class Company
def self.invoice_timeline
InvoiceTimeline.find :all, :from => '/company/invoice_timeline.xml'
end
def self.tax_timeline
TaxTimeline.find :all, :from => '/company/tax_timeline.xml'
end
end
class InvoiceTimeline < Base
self.prefix = '/company/'
end
class TaxTimeline < Base
self.prefix = '/company/'
end
# Contacts
class Contact < Base
end
# Projects
class Project < Base
def invoices
Invoice.find :all, :from => "/projects/#{id}/invoices.xml"
end
def timeslips
Timeslip.find :all, :from => "/projects/#{id}/timeslips.xml"
end
end
# Tasks - Complete
class Task < Base
self.prefix = '/projects/:project_id/'
end
# Invoices - Complete
class Invoice < Base
def mark_as_draft
connection.put("/invoices/#{id}/mark_as_draft.xml", encode, self.class.headers).tap do |response|
load_attributes_from_response(response)
end
end
def mark_as_sent
connection.put("/invoices/#{id}/mark_as_sent.xml", encode, self.class.headers).tap do |response|
load_attributes_from_response(response)
end
end
def mark_as_cancelled
connection.put("/invoices/#{id}/mark_as_cancelled.xml", encode, self.class.headers).tap do |response|
load_attributes_from_response(response)
end
end
end
# Invoice items - Complete
class InvoiceItem < Base
self.prefix = '/invoices/:invoice_id/'
end
# Timeslips
class Timeslip < Base
def self.find(*arguments)
scope = arguments.slice!(0)
options = arguments.slice!(0) || {}
if options[:params] && options[:params][:from] && options[:params][:to]
options[:params][:view] = options[:params][:from]+'_'+options[:params][:to]
options[:params].delete(:from)
options[:params].delete(:to)
end
case scope
when :all then find_every(options)
when :first then find_every(options).first
when :last then find_every(options).last
when :one then find_one(options)
else find_single(scope, options)
end
end
end
# Users
class User < Base
self.prefix = '/company/'
def self.find_by_email(email)
users = User.find :all
users.each do |u|
u.email == email ? (return u) : next
end
raise Error, "No user matches that email!"
end
end
end
config/initializers/freeagent.rb
Freeagent.authenticate({
:domain => 'XXXXX.freeagentcentral.com',
:username => 'XXXX#XXXXXXX.co.uk',
:password => 'XXXXXX'
})
The above render the following error when trying to create a new Case and send the details to FreeAgent:
ActiveResource::ResourceNotFound in KasesController#create
Failed with 404 Not Found
and
ActiveResource::ResourceNotFound (Failed with 404 Not Found):
app/models/kase.rb:56:in `create_freeagent_project'
app/controllers/kases_controller.rb:96:in `create'
app/controllers/kases_controller.rb:93:in `create'
Rendered rescues/_trace (176.5ms)
Rendered rescues/_request_and_response (1.1ms)
Rendering rescues/layout (internal_server_error)
If anyone can shed any light on this problem it would be greatly appreciated!
Thanks,
Danny
How are you calling create? With a normal restful create action it would be with a POST from a form or something, but 404s are generally rendered from a failed GET action, where an ActiveRecord find fails to locate a record with a specific id. My best guess is that you're calling create with a GET, and that the line
user = Freeagent::User.find_by_email(current_user.email)
simply cannot locate a user with that email, and so is throwing the ResourceNotFound exception.
Additionally, this bit of code is confusing to me:
#kase = Kase.new(params[:kase])
#company = Company.find(params[:kase][:company_id])
#kase = #company.kases.create!(params[:kase])
respond_to do |format|
if #kase.save
Why are you creating #kase twice here, once with Kase.new and once with kases.create? Also, note that the line:
if #kase.save
will always evaluate true, because the line:
#company.kases.create!(params[:kase])
would have thrown an exception if it were false, which is another way of saying that #kase.save is redundant because create! would have already persisted the new Kase record.
EDIT: What I think you meant to do was:
# this line can go #kase = Kase.new(params[:kase])
#company = Company.find(params[:kase][:company_id])
#kase = #company.kases.build(params[:kase])
EDIT: You probably want a new action like this:
def new
#kase = Kase.new # no params here
end
The 'new' erb template will have a form_for something like:
<% form_for #kase do |k| %>
etc. That form will by default post the params from the form to the create action, assuming you've set up something like resources :kase in your routes. That should get you started. Follow the standard tutorials like you're doing and things should get simpler as you go.