I created a new model named PaypalOrder using:
rails generate model order_id:integer ip_address:string first_name:string last_name:string card_type:string card_expires_on:date
Then I ran rake db:migrate
Now my order model looks like:
class PaypalOrder < ActiveRecord::Base
belongs_to :order
attr_accessor :card_number, :card_verification
validate :validate_card, :on => :create
def purchase
#code
end
private
def validate_card
#code
end
def credit_card
#code
end
end
and the controller i created:
class PaypalOrdersController < ApplicationController
def new
#paypal_order = PaypalOrder.new
end
def create
#paypal_order = current_order.build_paypal_order(params[:paypal_order])
if #paypal_order.save
# ...
else
render :action => "new"
end
end
end
But I'm getting the following error:
NameError in PaypalOrdersController#create
undefined local variable or method `current_order' for #<PaypalOrdersController:0xf7b0a34>
Why am I not able to access the current_order and how can I successfully build paypal_order
EDIT: made the following change:
class PaypalOrdersController < Spree::BaseController
works fine now!!
Why not change line 8 of your controller to:
#paypal_order = PaypalOrder.new(params[:paypal_order])
?
If it is Rails 4 you'll have to do:
#paypal_order = PaypalOrder.new(params.require(:paypal_order).permit!)
As per the error, current_order method does not exist.
You need to create current_order method first before calling it.
I am assuming that your intention with current_order was to reuse the order instantiated by the new action...
Since instance variables don't live through more than one request you need to instantiate the paypalorder again.
#paypal_order = PaypalOrder.new(params[:paypal_order])
enter code here
Related
Using Rails 4.1 and Devise 3.0.3, how can I create an associated object on User when User is instantiated and connect the two?
def User
has_one :case
end
def Case
belongs_to :user
end
In this case, User is set up with devise.
What I'd like to do is instantiate an object like so:
#case = Case.new
current_user.case = #case
or
current_user.case << #case
How can I execute this code when a request is made to "registrations#new"?
Here is how I would implement this:
class User < ActiveRecord::Base
...
before_action :create_case, only: [:new, :create]
def create_case
case = Case.create
self.case = case.id
# Maybe check if profile gets created and raise an error
# or provide some kind of error handling
end
end
Override create action of Devise::RegistrationsController and pass a block to it:
# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def create
super do
resource.case = Case.new
resource.save
end
end
end
You can use create method inside your User model. Something similar like this:
def self.create(username, email, pass)
user = User.new(:username => username, :email => email, :password => pass)
user.case = Case.new
return user if user.save
end
I think that you have to override Devise::RegistrationsController#create and in the create action you have to take resource and do something like this resource.build_case
https://github.com/plataformatec/devise/blob/master/app/controllers/devise/registrations_controller.rb
http://guides.rubyonrails.org/association_basics.html#has_one-association-reference
I have the following model in my Rails 3.2.13 build. I am trying to use it to insert data into my database.
class Financials < ActiveRecord::Base
#attr_accessible :description, :stock
attr_accessible :symbol, :cur_price
sym = Financials.new(:symbol => test, :cur_price => 10)
sym.save
end
but when I try to run the code I get the following error:
financials.rb:1:in `': uninitialized constant ActiveRecord (NameError)
I checked through SO and found others that had similar errors and they suggested that I add entries in the environment.rb ruby on rails pluralization help?
I added the following to the environment.rb file:
Inflector.inflections do |inflect|
inflect.irregular 'financialss', 'financials'
end
but it did resolve my issue. Thanks in advance
You don't create new objects inside the definition of the model. You should be doing this in the create action of the controller.
Given your model:
class Financial < ActiveRecord::Base
attr_accessible :symbol, :cur_price
# validations, methods, scope, etc.
end
You create the new Financial object in your controller and redirect to the appropriate path:
class FinancialsController < ApplicationController
def create
#financial = Financial.new(params[:financial])
if #financial.save
redirect_to #financial
else
render :new
end
end
def new
#financial = Financial.new
end
def show
#financial = Financial.find(params[:id])
end
end
Suppose I have this association:
class User < ActiveRecord :: Base
has_one :car
end
class Car < ActiveRecord :: Base
belongs_to :user
end
routes:
resources :users do
resources :cars
end
Then what would be the code, in the 'new' action method in CarsController
class CarsController < ApplicationController
def new
#??? what's necessary to be put here,
# if I have request 'localhost:3000/users/1/cars/new'
end
...
end
Will Rails figure out everything automatically so I don't have to write any code in the 'new' method? Also, since the 'new' action will generate a 'form_for(#car)' form helper, how can I create this car object
Is this right?
class CarsController < ApplicationController
def new
#user = User.find(params[:user_id])
#car = #user.build_car({})
end
end
That looks just fine. Rails will not do any of this automatically. There are gems out there that can automate some of that if you like, but the jury is out on whether they're actually worth your time.
If you have no params to pass to the car, you can just run #user.build_car with no arguments, by the way. You'll also need to specifically say in the form_for helper that you're nesting the car under the user: form_for [#user, #car] Otherwise the form's destination will be /cars instead of /user/1/cars.
You're pretty close, Baboon. I would actually do:
class UsersController < ApplicationController
def new
#user = User.new
#car = #user.cars.build
end
end
But if you don't want to create the Car at the same time as the user, try:
class CarsController < ApplicationController
def new
#user = User.find(params[:user_id])
#car = #user.cars.build
end
end
I found the nested_form railscast extremely helpful when doing this sort of thing. In fact, I think you'll probably get a lot out of it (and using the nested_form gem).
railscasts_196-nested-model-form-part-1
Looking for a way to either:
Change one of the fields of a new record (namely - force it to lower-case) before saving it to a RoR db.
I've tried:
before_create do |term|
term.myfield.downcase!
end
but this gives an error of:
undefined method `before_create' for RowsController:Class
or
Check that the field is all lowercase, and if not, raise an error message, and not create the record.
tried:
before_filter :check_lowcase, :only => [:new]
def check_lowcase
if (Term.new =~ /[^a-z]+/)
flash[:notice] = "Sorry, must use lowercase"
redirect_to terms_path
end
end
this seems to just be ignored....
You need to do it on your model, not your controller:
class YourModel < ActiveRecord::Base
before_create :downcase_stuff
private
def downcase_stuff
self.myfield.downcase!
end
end
before_create :lower_case_fields
def lower_case_fields
self.myfield.downcase!
end
before_save { |classname| classname.myfield = myfield.downcase }
A user can sign up as an artist. All the user needs to do now, is provide his email.
In Artist controller, def create. Is it normal to have something like:
def create
#artist = current_user
respond_to do |format|
if #artist.update_attributes(params[:user]) # params[:user] contains email
#artist.is_artist = true
#artist.save
....
In my User model, I have:
attr_accessible :email
Which means, I can't simply do #artist.update_attributes(:is_artist => true). I would have to use the save method instead. Is this type of approach common? Or is there a better way?
You can define before_create method in your model:
class User < ActiveRecord::Base
...
before_create :fill_fields
def fill_fields
is_artist = true
end
end
I would do the following:
1st: I wound not set up an ArtistController if you do not have an Artist Model. rather I would add a non-restful method in your UserController, and push the implemention logic into the model ...
# config/routes.rb
resources :users do
member {post 'signup_as_artist'}
end
# UserController
def signup_as_artist
#user = User.find(params[:id])
#user.signup_as_artist
end
# User
def signup_as_artist
self.update_attribute :is_artist, true
end
Good luck