将变量传递给Rails控制器方法

时间:2011-07-11 20:48:48

标签: ruby-on-rails ruby ruby-on-rails-3

我正在修改Rails的MobileFu插件(https://github.com/brendanlim/mobile-fu)以接受是否打开插件的参数。

在控制器中,您可以调用以下内容:

class ApplicationController < ActionController::Base
  has_mobile_fu
end

但我想这样做:

class ApplicationController < ActionController::Base
  has_mobile_fu :mobile_enabled

  def mobile_enabled
    current_account.mobile_enabled?
  end
end

其中current_account由子域查找设置。问题是,当我传入:mobile时,它只传递符号,而不是:mobile的值。

以下是相关的MobileFu代码:https://github.com/brendanlim/mobile-fu/blob/master/lib/mobile_fu.rb

这是我的编辑:

def has_mobile_fu(enabled, options = {})
  include ActionController::MobileFu::InstanceMethods

  logger.info "Enabled is: "  + enabled.to_s  

  before_filter(options) do |controller|
    controller.set_mobile_format(enabled)
  end

  helper_method :is_mobile_device?
  helper_method :in_mobile_view?
  helper_method :is_device?
end

如果我在控制器中使用静态参数调用它(即has_mobile_fu(false)),它可以正常工作。当我试图传入变量(即has_mobile_fu :mobile_enabled)时,我遇到了麻烦。变量只是作为符号出现(因此上面的记录器输出将为Enabled is: mobile_enabled

谢谢!

2 个答案:

答案 0 :(得分:0)

这里有点混乱。

  • 在控制器中定义has_mobile_fu时,它是一个类方法,而不是实例方法。

  • 如果您想将args传递给某个方法,请将其视为哈希:has_mobile_fu :mobile_enabled => "somevalue"

所以在你的方法定义中,如果你有:

def has_mobile_fu args

您可以使用args[:mobile_enabled]

获取值

最后,因为您希望根据current_account获取值,请考虑传递Lambda。

答案 1 :(得分:0)

这是一个想法的草图。我总是喜欢让方法“聪明”。所以方法的用户(你)不需要考虑太多。它应该工作。考虑到这一点:

# 1: Modify has_mobile_fu to something like this:
def has_mobile_fu(enabler = false, &block)
  include ActionController::MobileFu::InstanceMethods
  enabler = block if block_given?

  case enabler
  when Proc
    # Determine if we enable or not by calling proc
    before_filter { |controller|
      controller.set_mobile_format if enabler.call(controller)
    }
  when Symbol
    # Call the method named by the symbol instead
    before_filter { |controller|
      controller.set_mobile_format if controller.send(enabler)
    }
  # Old behaviour below
  when true
    before_filter :force_mobile_format
  else
    before_filter :set_mobile_format
  end

  # Rest is like the old method...
  ...
end

使用上述设置,您可以像这样使用它:

class ApplicationController < ActionController::Base

  # The old way
  has_mobile_fu

  # The old way, forcing mobile format
  has_mobile_fu true 

  # The new way using a symbol that signifies a method to call
  # to determine if we're enabling or not
  has_mobile_fu :mobile_enabled

  # The new way using an in-line proc method
  has_mobile_fu { |controller| controller.mobile_enabled }

  def mobile_enabled
    ...
  end
end

这种方式“只是有效”。它是向后兼容的,如果你提供一个符号或一个proc,那么它们将被用作被调用以检查是否启用的方法。

注意..代码未经测试,但希望你能得到一般的想法。

编辑:简化代码......