Rails 4 before_action, pass parameters to invoked method
before_action only: [:show, :edit, :update, :destroy] do
set_support("value")
end
Rails: How to pass parameter to custom before_action class?
Okey, I managed to solve it.
I noticed that rails documentation mentioned *_action
to call a method with the same name as * specifies. So, before_action
seeks for a method named before
in a given class.
Therefore I decided to make a block and call AuthenticationFilter
before action directly by giving it the parameter:
before_action { |c| AuthenticationFilter.before(c, :superuser) }
Then I modified my AuthenticationFilter
class to be like:
class AuthenticationFilter
class << self
def before(controller, role)
puts "Called AuthenticationFilter with role: #{role}"
end
end
end
Hence, also noticed that using typical only
and except
rules works as well when doing:
before_action only: [:show, :edit] do |c|
AuthenticationFilter.before(c, :superuser)
end
Accessing action arguments in before_action
As you mentioned, you won't have access to instance variables set in ApplicationController
when you're inside a mailer action. It's really easy to pass that data in from the controller, however. Here's a simple example:
class ApplicationController < ActionController::Base
before_action :load_settings
private
def load_settings
@settings = "foo"
end
end
class UserController < ApplicationController
def email
UserMailer.welcome_message(@settings).deliver_now
end
end
class UserMailer < ApplicationMailer
def welcome_message(settings)
@settings = settings
mail to: "to@example.org"
end
end
The example is a little contrived, but this would make @settings
available in the mailer view. I tested this locally with a fresh Rails app and it worked as expected.
Pass return value of 'before_action' to coming actions
This is done by assigning to controller instance variables.
before_action :new_mpd
def status
# use @mpd
end
private
def new_mpd
@mpd = MPD.new
@mpd.connect
end
How to use before_action with :unless and params
before_action do |controller|
unless params[:user_id].to_i == current_user.id
controller.authorize
end
end
Alternatively you can do so like:-
before_action :authorize
def authorize
unless params[:user_id].to_i == current_user.id
#do your stuff..
end
end
2nd Alternative
before_action :authorize, unless: -> { params[:user_id].to_i == current_user.id }
before_filter with parameters
I'd do it like this:
before_filter { |c| c.authenticate_rights correct_id_here }
def authenticate_rights(project_id)
project = Project.find(project_id)
redirect_to signin_path unless project.hidden
end
Where correct_id_here
is the relevant id to access a Project
.
rails How to pass params fro new to create block
What solved my problem was to use session params.
A session is just a place to store data during one request that you can read during later requests.
I decided to use session hash to store the resource id params I get from the new link in the resource it was called from and then use the session hash to retrieve the parent to redirect to after a review has been created. Also, I don't need to use hidden fields for this to work.
class ReviewsController < InheritedResources::Base
before_action :authenticate_user!, only: [:new, :create, :destroy, :update]
before_action :set_child_and_parent, only: [:destroy, :update, :edit]
def new
@review = Review.new
session[:parent_id] = params[:parent_id]
session[:parent_type] = params[:parent_type]
@parent = get_parent(params[:parent_type], params[:parent_id])
@owner = User.find_by_id(@parent.user_id)
end
def create
@review = Review.new(review_params)
@review.user_id = current_user.id
@parent = get_parent(session[:parent_type], session[:parent_id])
@owner = User.find_by_id(@parent.user_id)
@review.owner_id = @owner.id
respond_to do |format|
if @review.save
format.html { redirect_to @parent, notice: 'Review was successfully created.' }
format.json { render :show, status: :created, location:@review }
else
format.html { render :new }
format.json { render json: @review.errors, status: :unprocessable_entity }
end
end
end
private
def review_params
params.require(:review).permit(:comment, :rating)
end
def set_child_and_parent
@review = Review.find_by_id(params[:id])
end
def get_parent(parent_type, parent_id)
if parent_type == "repairshop"
parent = Repairshop.find_by_id(parent_id.to_i)
elsif parent_type == "listing"
parent = Listing.find_by_id(parent_id.to_i)
else
parent = root_path
end
return parent
end
end
Related Topics
Good Cucumber Examples in the Wild
Strip Signatures and Replies from Emails
How to List All Versions of a Gem Available at a Remote Site
How to Set Up a Sinatra App Under Apache with Passenger
Manually Retry Job in Delayed_Job
Passing a Hash to a Function ( *Args ) and Its Meaning
How to Upgrade to the Current Version of Ruby (2.2.3) on Os X V10.6.8
Stop Rails Console from Printing Out the Object at the End of a Loop
All Ruby Tests Raising: Undefined Method 'Authenticate' for Nil:Nilclass
How to Create a Copy of Some Columns of a CSV File in Ruby with Different Data in One Column
How to Define a 'Before_Save' Callback in a Module
Ruby Metaprogramming Online Tutorial
Rspec Allow/Expect VS Just Expect/And_Return
Error Installing Debugger-Linecache in Ruby 1.9.3
Rails with Paypal Permissions and Paypal Express Checkout