How does implicit Rails rendering work with super in controller methods? - ruby-on-rails

In the below, will the implicit render still get called in the SpecialArticlesController? Or will it get skipped to the implicit render in ArticlesController?
class SpecialArticlesController < ArticlesController
def index
...
super
end
end
class ArticlesController
def index
...
end
end

You will not get a double render error, unless you are explicitly rendering twice. This code will cause an error:
class ParentController < ApplicationController
def index
render
end
end
class ChildController < ParentController
def index
render
super
end
end
Whereas the code below will not cause an error:
class ParentController < ApplicationController
def index
end
end
class ChildController < ParentController
def index
super
render
end
end

Related

filter methods in before_action after of another before_action

how can I filter a second before_action?, I have two controllers, and when I call the method A, a before_action executes a methodB, but before executing this second method I would like to execute a general methodC, but in this method I need to pass a parameter to know where is coming from, but if I use a second before_action this doesn't work, because "only" in before_action filters using the first method method (which is methodA), what can I do?
class FirstController < SecondController
before_action :methodB
def methodA
#some code
end
end
class SecondController < ApplicationController
before_action only: [:methodB] do
methodC('methodB')
end
def methodB
#some code new
end
end
class ApplicationController < ActionController::Base
def methodC(method)
#general method
end
end
This is the structure that I have:
I'm out of practice with rails but would the following be acceptable?
class FirstController < SecondController
before_action :methodB
def methodA
#some code
end
private
def should_call_C
action_name == :methodA
end
end
class SecondController < ApplicationController
before_action do |controller|
methodC if controller.should_call_C
end
def methodB
#some code new
end
private
def should_call_C
action_name == :methodB
end
end
class ApplicationController < ActionController::Base
def methodC
#general method
# can use action name to get method rather than passing it?
end
end

access params inside initialize (constructor) of the controller

I have to change the value of keys inside params of a controller. I don't want to do it each method but do it at a constructor level. But when I access it inside initialize I get this error
"NoMethodError (undefined method `parameters' for nil:NilClass):"
class MyController < ApplicationController
def initialize
puts params.inspect #params is nil!
end
end
I also tried to do that using before_action but the same error
class MyController < ApplicationController
before_action :my_initializer
def initialize
puts params.inspect #params is nil!
end
def my_initializer
puts params.inspect #params is nil!
end
end
Thanks
You should use before_action without initialize to make it work:
class MyController < ApplicationController
before_action :my_initializer
def my_initializer
puts params.inspect
end
end

Rails pass value/object/orm from parent controller to child

To keep to restfull protocol, I need to do /api/backup_jobs/777/errors.
In rails, the parent controller- I have:
module Api
class BackupJobsController < ApplicationController
respond_to :json
def show
#backup_job = #backup_jobs.find(params[:id])
respond_with data: #backup_job
end
end
end
in the child controller:
module Api
class ErrorsController < BackupJobsController
respond_to :json
def index
respond_with data: #backup_jobs.find(params[:id]).backup_events.errors
end
end
end
But obvisouley this isn't going to work because params[] doesn't exist for /api/backup_jobs/777/errors
How can I pass the #backup_job = #backup_jobs.find(params[:id]) from the parent controller's def show to the child controller and have it accessible in the child's def index?
You cannot do that because when an ErrorsController is created and used, you will not have a BackupsJobsController that ran before it.
This comes down to the nature of HTTP being a request-response protocol.
Instead, you can extract the line of code you wrote into a method that will be inherited by the ErrorsController.
backup_jobs_controller.rb:
module Api
class BackupJobsController < ApplicationController
def show
find_backup_job
respond_with data: #backup_job
end
protected
def find_backup_job
#backup_job = #backup_jobs.find(params[:id])
# or maybe #backup_job = BackupJob.find(params[:id])
end
end
end
errors_controller.rb:
module Api
class ErrorsController < BackupJobsController
respond_to :json
def index
respond_with data: find_backup_job.backup_events.errors
end
protected
def find_backup_job
#backup_job = BackupJob.find(params[:backup_job_id])
end
end
end

How can I pass variable from one controller to another? (rails)

I have controller with action (welcome#index):
class WelcomeController < ApplicationController
def index
#card = current_user.cards.review_before(Date.today).first
#my_test_variable #this variable from another controller
end
end
and I have another controller:
class CardsController < ApplicationController
def review
if #card.check = true
#my_test_variable = 1
else
#my_test_variable = 2
end
redirect_to root_path #redirect to welcome#index
end
end
How can I put #my_test_variable value to action index controller Welcome to use it in view index?
I think what you're asking is how to make them available to the next request. Put them in the session:
class CardsController < ApplicationController
def review
if #card.check = true
session[:my_test_variable] = 1
else
session[:my_test_variable] = 2
end
redirect_to root_path #redirect to welcome#index
end
end
class WelcomeController < ApplicationController
def index
#card = current_user.cards.review_before(Date.today).first
session[:my_test_variable]
end
end
I will not question why you would want to do this but one solution is redirect to root_path with a parameter and then grab it in the other controller:
class CardsController < ApplicationController
def review
if #card.check == true
#my_test_variable = 1
else
#my_test_variable = 2
end
redirect_to root_path(my_test_variable: #my_test_variable)
end
end
class WelcomeController < ApplicationController
def index
#card = current_user.cards.review_before(Date.today).first
#my_test_variable = params[:my_test_variable] # will be a string
end
end
(and btw, you have a typo in the if statement. should be ==, not =)
The easy way would be making the variable global so that it can be assessed from any controller and later making it null.
class ModelController < ApplicationController
def index
$count = 125
end
end
class PaymentController < ApplicationController
def price
puts $count
end
end
The login in the cards controller should probably be in the model, then you don't have to worry about the approach you have taken.
It is highly uncommon to have 2 controller instances involved with processing one request.

Rails3 layout not render for some controller

This is my application_controller.rb
class ApplicationController < ActionController::Base
layout :my_layout
private
def my_layout
request.path.match(/folder/) ? 'layout1' : 'layout2'
end
end
In this controller default layout method called and layout2 render post/promotion_controller.rb
class Post::PromotionsController < ApplicationController
def index
end
end
But in this controller user/users_request_controller.rb layout method not called and no layout render
class User::UserRequestsController < User::UserController
def index
end
end
class User::UserController < ApplicationController
def index
end
end
Please help me why my layout method not called.
I am using rails3.2.14 and ruby 1.9.3p392
Try declaring the my_layout method as protected rather than private
That might do the trick

Resources