문제

Behold, a before_filter:

class ThingController < ApplicationController
  before_filter :check_stuff, :if => proc {Rails.env.production?}
end

During a recent code review, I was asked, "Is the proc is required for this to work?" The answer appears to be 'yes', but it's a reasonable question, and I had intended to answer it by referring to the Rails docs or guides or something on the use of conditionals with before_filter (now an alias of before_action).

I couldn't find any. The Action Controller Guide mentions :only/:except, but not :if/:unless.

Failing that, is there somewhere in the code I can point to that covers this? It's mentioned briefly here, but that's more about how :only and :except are handled, rather than :if or :unless.

도움이 되었습니까?

해결책

Found it on Rails Guides: http://guides.rubyonrails.org/active_record_callbacks.html#conditional-callbacks

Turns out a Proc isn't always required for it to work.

the :if and :unless options, which can take a symbol, a string, a Proc or an Array.

So in your case you could probably get away with

before_action :check_stuff, if: "Rails.env.production?"

Finding things in Rails documentation can be a pain sometimes, but at least questions like this make things easier to find over time since StackOverflow is well indexed and has high search rankings.

다른 팁

From Rails 5.2 onwards, the current accepted answer is no longer be valid, and passing a string to the conditional will fail.

DEPRECATION WARNING: Passing string to :if and :unless conditional options is deprecated and will be removed in Rails 5.2 without replacement.

Going forward, a proc is now the best way to add a conditional like in the original question:

class ThingController < ApplicationController
  before_action :check_stuff, :if => proc {Rails.env.production?}
end

i have done this on my code while ago. I hope that example helps to you. If you can use if statement but that should point to another method like I did here.

class Admin::ArticlesController < ApplicationController
  before_filter :deny_access, :unless => :draft_and_admin?

  def show
    @article = Article.find(params[:id])
  end

  protected

  def draft_and_admin?
    Article.find(params[:id]).draft? && current_user.admin?
  end
end

I would recommend using staby lambda. If you want know, WHY? Please read this

class ThingController < ApplicationController
  before_action :check_stuff, if: -> { Rails.env.production? }
end

which is almost equivalent to Upvote Me's answer.

Adding a method to check the if/unless conditions for a before_action should be the best way as this way you can easily accommodate any additional changes in the before_action conditions easily in future:

class ThingController < ApplicationController
  before_filter :check_stuff, if: :check_stuff?

  def check_stuff
  end

  private

  def check_stuff?
    Rails.env.production?
  end
end
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top