ruby - 把这个 haml 片段变成一个帮助器来干燥 Sinatra

标签 ruby sinatra haml

这个 haml 有效:

%select{ :name => 'color', :value => @p.color}
  - Person.color.options[:flags].each do |colors|
    - if @p.color == colors
      %option{:value => colors, :selected => "selected"}= colors
    - else
       %option{:value => colors}= colors

我正在尝试用它创建一个助手,以便我可以重用它:

helpers do
  def options(prop, p)
    Person.prop.options[:flags].each do |x|
      if p.prop == x
        "%option{:value => #{x}, :selected => 'selected'}= #{x}"
      else
        "%option{:value => #{x}}= #{x}"
      end  
    end
  end
end

然后用以下方式调用它:

%select{ :name => 'color', :value => @p.color}
  - options(color, @p)

但我收到此错误:undefined local variable or method 'color'

我还差得远吗?

编辑2:

循环中发生了一些奇怪的事情。

即使是像这样的简单示例:

helpers do
  def options(prop, p)
    Person.send(prop).options[:flags].each do |x|
    "<p>test</p>"
    end
  end
end

= options(:color, @p)

打印选项数组(在我的例子中为 [:red, :blue, :yellow] )并且不插入任何 html。但是,如果我这样做puts <p>test</p>它确实执行了三次循环并正确打印它们 - 它们只是没有显示在 html 中。

最佳答案

使用符号代替未定义的方法:

options(:color, @p)

而不是:

options(color, @p)

并在辅助方法上使用send:

if p.send(prop) == x

而不是

if p.prop == x

以及:

Person.send(prop)

而不是:

Person.prop

此外,我怀疑 HAML 是否会接受像 "%option{:value => #{x}" 这样的字符串作为标签。

您可以使用 HTML 来代替,或者只是寻找另一种 DRY 方法,例如渲染部分或使用 haml_tag:

def options(prop, p)
  Person.send(prop).options[:flags].each do |x|
    haml_tag :option, "#{x}", :value=>x
  end
end

如果您使用haml_tag,请使用- options(:color, @p) 调用它

关于ruby - 把这个 haml 片段变成一个帮助器来干燥 Sinatra,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13656241/

相关文章:

ruby-on-rails - Capistrano 在部署时要求输入密码,尽管有 SSH key

ruby-on-rails - 如何从 format.xml 中删除 <hash></hash>

ios - 获取 google people profile API 不返回生日和性别键值

ruby - Rspec/Sinatra 模块化与经典风格

ruby - 如何在 Heroku 上托管的 Ruby/Sinatra 应用程序中设置 HTTP header ?

ruby - 在 Sinatra 中,我可以在路由和 View 中使用变量吗?

haml - 如何从HAML的pre标签中删除不需要的缩进

javascript - 创建一个复制数组元素的按钮

ruby-on-rails - 将日期范围转换为周和月数组

ruby-on-rails - 10001 尝试使用 Activemerchant 从 PayPal 获取授权时出现内部错误