Reputation: 8294
I have two methods that I wish to run in several controller actions.
def get_offer
@offer = Offer.find_by :uuid => params[:offer_id]
if @offer.blank?
error_response = ErrorResponse.new("Offer not found")
render json: error_response, :status => :not_found and return
end
end
def validate_api_v2
api_version = params[:api_version]
if api_version != api_version_to_validate
error_response = ErrorResponse.new("API version not supported")
render json: error_response, :status => :bad_request and return
end
end
How can I run both of them in actions action_a
, action_b
, only one in action_c
and action_d
, and none of them in action_e
?
Upvotes: 4
Views: 7221
Reputation: 5802
You could probably do it like this:
before_action :get_offer, only: [:action_a, :action_b, :action_c]
before_action :validate_api_v2, only: [:action_a, :action_b, :action_d]
Edit: colons were missing for the second line only and action_id
Upvotes: 4
Reputation: 765
write the methods in a controller concern. For example:
# app/controllers/concerns/example_concern.rb
module ExampleConcern
extend ActiveSupport::Concern
protected
def get_offer
@offer = Offer.find_by :uuid => params[:offer_id]
if @offer.blank?
error_response = ErrorResponse.new("Offer not found")
render json: error_response, :status => :not_found and return
end
end
def validate_api_v2
api_version = params[:api_version]
if api_version != api_version_to_validate
error_response = ErrorResponse.new("API version not supported")
render json: error_response, :status => :bad_request and return
end
end
end
Now in the controller, include the module in the concern and call the methods using before_action as required. For example:
# app/controllers/examples_controller.rb
class ExamplesController < ApplicationController
include ExampleConcern
before_action :get_offer, only: [:action_a, :action_b, :action_c]
before_action :validate_api_v2, only: [:action_a, :action_b, :action_d]
def action_a
end
def action_b
end
def action_c
end
def action_d
end
def action_e
end
end
Upvotes: 1
Reputation: 1601
Try this one
before_filter :action_a, :action_b, only: [:action_c, :action_d]
Upvotes: 3
Reputation: 4032
except
comes in handy for some cases:
before_action :get_offer, only: [:action_a, :action_b, :action_c]
before_action :validate_api_v2, except: [:action_e, :action_c]
Upvotes: 0
Reputation: 16002
Move get_offer
and validate_api_v2
to ApplicationController
and then in rest of your controllers, for example you can do:
class SomeController < ApplicationController
before_filter :get_offer, :validate_api_v2, :only => [:action_a, :action_b]
end
and:
class SomeOtherController < ApplicationController
before_filter :get_offer, :only => [:action_c, :action_d, :action_e]
before_filter ::validate_api_v2, :only => [:action_c, :action_d]
end
I hope you get the point.
Upvotes: 1