How to use Model in diffrent controller with ROR - ruby-on-rails-3

I am new new ROR and i am using ruby 1.9.3 and rails 3 version
I want to use Model in different controller.
For ex: My Controller name PackagesController and I want use OrderHistory Model in PackagesController.
See below code
class PackagesController < ApplicationController
def paypal
#data = params
#User.create(:name => "user1",:address=>"address1")
#package_id = #data[:pid]
#package_price = #data[:pprice]
OrderHistory.create(:admin_user_id => "1", :package_id=>package_id, :price=>package_price, :payment_status=>'pending' )
end
end
This code very time given error uninitialized constant PackagesController::OrderHistory
Please help

You can use any model in any controller. The problem elsewhere
Make sure that you have model class named OrderHistory saved in the file named order_history.rb

Related

Rails Routing: One controller. One model with type. Multiple routes

I have one model named Factors, which has two types: ['personal', 'advisor']
I want to have one controller FactorsController that has all the same actions for both types of Factors, but only ever uses one type. The type that it uses is based on the route used to get there. For example,
/personal would route to factors#index and populate #factors with Factor.personal
/advisors would route to factors#index and populate #factors with Factor.advisors
How would I go about setting this up?
You can add to the routes
type_regexp = Regexp.new([:personal, :advisor].join("|"))
resources :factors, path: ':type', constraints: { type: type_regexp }
and you will be able to user params[:type] in the controllers, that gives you flexibility in case you wanna changes the routes in the future.
This also gives you the ability to use factors_path(type: :personal) in the views.
You can add this to your routes:
resources :factors, :path => :personal
resources :factors, :path => :advisor
This will then have both /personal and /advisor. You'll then want to have factors#index determine which path was used (you could use request.url) and populate #factors accordingly.
I would create three controllers:
class PersonalController < FactorController
def factor
Factor.personal
end
end
class AdvisorController < FactorController
def factor
Factor.advisors
end
end
class FactorController < ApplicationController
#all the shared stuff here, using the factor method from each in your methods
end
and then the routes would be:
route '/personal' => PersonalController#index
route '/advisors' => AdvisorController#index

How I can setup controller/response object from scratch to run render_to_string?

How I can setup controller/response objects from scratch to ran render_to_string?
I developed an application which generate a PDF file.
I used erb based template to generate TeX file, then process it to convert to PDF.
It's working fine, but I now start thinking it is better to generate the report in background. Thus, I created a queuing system using delayed_job and it's working well.
Now, when combine two of them, I realized that renderer implemented as part of controller.
What I want to do is run render_to_string to generate the PDF. It looks like I need to setup controller and response object from scratch.
I found a question (How do I call controller/view methods from the console in Rails?) relate to this, but setting up a response object by calling post seems awkward.
How I can setup controller and response object to achieve this?
Here's one way to do it (generating the PDF via wicked_pdf):
Controller:
class FoosController < ApplicationController
def queue_pdf_generation
#foo = Foo.find(params[:id])
Delayed::Job.enqueue GeneratePdfJob.new(#foo.id)
end
end
Delayed Job:
class GeneratePdfJob < Struct.new(:foo_id)
def perform
# get the Foo object when the job is run
foo = Foo.find(foo_id)
# create an instance of ActionView, so we can use render method outside of a controller
av = ActionView::Base.new()
av.view_paths = ActionController::Base.view_paths
pdf_html = av.render :template => "foos/pdf.html.erb", :layout => nil, :locals => {:foo => foo}
# use wicked_pdf gem to create PDF from the foo HTML
foo_pdf = WickedPdf.new.pdf_from_string(pdf_html, :page_size => 'Letter')
# save PDF to disk
pdf_path = Rails.root.join('tmp', "#{foo.id}.pdf")
File.open(pdf_path, 'wb') do |file|
file << foo_pdf
end
end
A couple notes:
The "perform" method doesn't take a parameter; inheriting from a
struct lets us pass a parameter to the GeneratePdfJob object, and it
sets up a local variable called "foo_id" that we can use in the
"perform" method.
Your view needs to reference the local variable
"foo" rather than an instance variable "#foo".

using build method on association in rails 3.2 creating object in memory

I have 2 models like the following
Class Post
has_many :comments, :dependent => :destroy
end
Class Comment
validates_presence_of :post
validates_presence_of :comment
belongs_to :post
end
In Comments controller,
def create
comment = #post.comments.build(params[:comment])
if comment.save
// some code
else
// some code
end
end
When the comment is invalid as per the validation, the comment is not saved. But when the #post object is accessed in the view, it contains a comment object with nil id. This did not happen in Rails 2.3.11. We are upgraded to Rails 3.1 and then now to Rails 3.2. This comment object with nil id disappears when I do #post.reload. We are using REE.
I tried to interchange build and new methods. It had the same result as build. Similar behavior is found across our application. Is it the expected behavior or am I doing something wrong?
This seems like expected behaviour to me.
via http://guides.rubyonrails.org/association_basics.html#belongs_to-association-reference
4.1.1.3 build_association(attributes = {})
The build_association method returns a new object of the associated
type. This object will be instantiated from the passed attributes, and
the link through this object’s foreign key will be set, but the
associated object will not yet be saved.
When you call #post.comments.build(...), Rails:
Creates a new Comment object
sets comment.post_id to #post.id.
Inserts it into the comments array (in memory).
When the validation fails, it doesn't delete the comment and the comment persists in the in-memory comments array. When #post gets to your view, #post.comments still includes that badly validated comment.
As for how to deal with it, I'm not sure. Maybe you could do something like (in your controller)... (Feels pretty ugly though.)
def create
comment = #post.comments.build(params[:comment])
if comment.save
// some code
else
#bad_comment = #post.comments.pop
end
end
I had a similar problem while using rails 3.2
Firstly, you need to create two separate methods in your controller. They will be as follows:
The 'new' method that is used to build your comments using 'build_association'
def new
#post = Post.new
comment = #post.build_comments
end
The 'create' method to actually create your comments using 'create_association'
def create
#post = Post.new(params[:post])
comment = #post.create_comments(params[:post][:comment_attributes])
if comment.save
// some code
else
#bad_comment = #post.comments.pop
end
end
Note: I suggest passing 'comment' attribute as a nested attribute of 'post' through your form using 'fields_for'.
Please refer:
http://apidock.com/rails/ActionView/Helpers/FormHelper/fields_for
http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

How Modify route standard Rails3?

I am using Rails3 and I would like make one request for get one parameter token to my controller different of ID to my action "confirms "in my controller,can someone help me?
I believe is a problem in my route.
such as:
http://0.0.0.0:3000/emails/1QWD3DF2Cd/confirms or http://0.0.0.0:3000/emails/confirms/1QWD3DF2Cd
`
class EmailsController < ApplicationController
def confirms
#email = Email.find(params[:token])
#email.confirmed # other method in model emails which mark as enable
end
end
`
You can do this
Add this to your routing.rb file.
match '/emails/confirms/:token' => 'emails#confirms', :as => 'confirms_emails'

How to call correctly methods from a model relating to other controllers?

In my Ruby on Rails application I want to create a new profile and a new statistic for profile, all calling first the related method from the user model, and then from the profile model.
So...
... in my user model (user.rb) I have this:
...
has_one :profile
...
before_save :inizialize_user
...
private
def inizialize_user
#user_profile = Profile.new
self.user_profile_id = #user_profile.id
end
... in my profile model (profiles.rb) I have this:
...
belongs_to :user
...
before_save :inizialize_profile
private
def inizialize_profile
#profile_statistic = ProfileStatistic.new
end
In the second block of code, on the "before_save" it instantiates a new profile statistic:
"inspecting" #profile_statistic results a new object (correct!)
In the first block of code, on the "before_save" it doesn't instantiate a new profile:
"inspecting" the #user_profile results nil (it must be a new profile object!)
The last part is my problem. Why it happens?
When you call Profile.new, it only creates an instance in memory, it isn't saved to the database and therefore doesn't have an id attribute (i.e. #user_profile.id is nil).
I suggest you replace
#user_profile = Profile.new
with
#user_profile = Profile.create
create will save the instance and then #user_profile.id will not be nil.
You probably also wan to use before_create callbacks (not before_save), or you'll have new user profiles every time you save the model (e.g. after udpating). Also, you probably want to have
ProfileStatistic.create
instead of
ProfileStatistic.new