Rails 4 Before_Action, Pass Parameters to Invoked Method

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



Leave a reply



Submit