检查方法是否响应Rails中的另一个方法?

时间:2015-07-17 10:10:31

标签: ruby-on-rails ruby ruby-on-rails-4

我的控制器:

class DashboardController < ApplicationController
  before_action :show_dashboard_menu, only: :index

  def index
    ...
  end

  private

  def show_dashboard_menu
    true
  end
end

我想在几个控制器之间传播方法show_dashboard_menu,并检查我是否需要从帮助方法显示特定操作的菜单:

我的帮手:

def show_dashboard_menu?
  true if current_action responds to show_dashboard_menu
end

然后在视图中使用它来显示或隐藏仪表板菜单:

show_dashboard_menu?

2 个答案:

答案 0 :(得分:1)

Ruby对象有一个名为respond_to的方法? (如果是方法和属性,请注意)

2.2.1 :001 > 1.respond_to?("to_s")
 => true 
2.2.1 :002 > 1.respond_to?("each")
 => false 
2.2.1 :003 > [].respond_to?("each")
 => true 
2.2.1 :004 > [].respond_to?("something")
 => false 
2.2.1 :005 > 

或者您也可以只询问方法或public_methods

2.2.1 :010 > 2.methods.include?(:real)
 => true 
2.2.1 :011 > 2.public_methods.include?(:real)
 => true 
2.2.1 :012 > 2.methods
 => [:to_s, :inspect, :-@, :+, :-, :*, :/, :div, :%, :modulo, :divmod, :fdiv, :**, :abs, :magnitude, :==, :===, :<=>, :>, :>=, :<, :<=, :~, :&, :|, :^, :[], :<<, :>>, :to_f, :size, :bit_length, :zero?, :odd?, :even?, :succ, :integer?, :upto, :downto, :times, :next, :pred, :chr, :ord, :to_i, :to_int, :floor, :ceil, :truncate, :round, :gcd, :lcm, :gcdlcm, :numerator, :denominator, :to_r, :rationalize, :singleton_method_added, :coerce, :i, :+@, :eql?, :remainder, :real?, :nonzero?, :step, :quo, :to_c, :real, :imaginary, :imag, :abs2, :arg, :angle, :phase, :rectangular, :rect, :polar, :conjugate, :conj, :between?, :nil?, :=~, :!~, :hash, :class, :singleton_class, :clone, :dup, :itself, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :freeze, :frozen?, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :extend, :display, :method, :public_method, :singleton_method, :define_singleton_method, :object_id, :to_enum, :enum_for, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, :__id__] 

因此,在ApplicationController中,您可以执行类似

的操作
def show_dashboard_menu?
  self.respond_to? "show_dashboard_menu"
end

答案 1 :(得分:0)

您可以在before_action中使用ApplicationController并在特定控制器中定义show_dashboard_menu?方法。

class ApplicationController < ActionController::Base
  before_action only: :index do |ctrl| 
    @show_dashboard_menu = ctrl.try(:show_dashboard_menu?) 
  end
end

class DashboardController < ApplicationController
  def show_dashboard_menu?
    whatever_logic
  end
end

然后在视图中使用@show_dashboard_menu变量。 我不喜欢的一件事是show_dashboard_menu?必须公开。但是,您可以使用attribute而不是方法,并将其设置为before_action。