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
Related
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
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
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
In Rails, if yield is a closure inside a layout, then how does controller can dictate which layout to render?
layout :render => "myLayout"
The layout command in a controller can also accept a symbol, which links it to a method. Like so:
class ApplicationController < ActionController::Base
layout :layout_by_resource
protected
def layout_by_resource
if devise_controller? && resource_name == :admin_user
"devise_admin"
else
"application"
end
end
end
So, you can use this to switch out which layout you want to use from within the controller.
If you want to set a layout for an controller
class YourController < ApplicationController
before_filter :set_layout
protected
def set_layout
render :layout => 'Your-layout'
end
end
I have the following method in my controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
private
def check_api_credential(api_key)
if Credential.find_by_key(api_key)
true
else
false
end
end
end
In all the controllers located directly under controllers folder, this method is reachable.
But the controllers files at controllers/api/v1/photos_controller.rb
module Api
module V1
class PhotosController < ActionController::Base
respond_to :json
def create
redirect_to root_url if check_api_credentials(params[:params][2])
if Photo.create(params[:params][0])
render 'success'
else
render 'failure'
end
end
end
end
end
When I try to save I get
undefined method 'check_api_credentials'
How can I access those methods from application_controllers.rb? They are inside of controllers folder.
class ApplicationController < ActionController::Base
class PhotosController < ActionController::Base
Doesn't ring a bell? All other controllers "directly under controllers folder" are inherited from ApplicationController, but PhotosController is not a child of ApplicationController, it is its sibling. That's why it doesn't see the method.
Is there a reason why you didn't inherit PhotosController from ApplicationController?
In your controller or where ever you need to call the private method in different location, you could try a try: method. So in your code,
def create
redirect_to root_url if try: check_api_credentials(params[:params][2])
if Photo.create(params[:params][0])
render 'success'
else
render 'failure'
end
end
It's might solve. Not sure... Just try to add this and run it....