Rails-嵌套的content_tag

88

我正在尝试将内容标签嵌套到自定义辅助函数中,以创建类似于这样的东西:

<div class="field">
   <label>A Label</label>
   <input class="medium new_value" size="20" type="text" name="value_name" />
</div>

请注意,该输入框并未与表单相关联,它将通过javascript保存。

这是助手(它不仅会显示html):

module InputHelper
    def editable_input(label,name)
         content_tag :div, :class => "field" do
          content_tag :label,label
          text_field_tag name,'', :class => 'medium new_value'
         end
    end
end

<%= editable_input 'Year Founded', 'companyStartDate' %>

然而,当我调用helper时,标签未显示,只有输入框被显示出来。如果注释掉text_field_tag,则标签会被显示。

谢谢!

4个回答

163

你需要一个 + 来快速解决 :D

module InputHelper
  def editable_input(label,name)
    content_tag :div, :class => "field" do
      content_tag(:label,label) + # Note the + in this line
      text_field_tag(name,'', :class => 'medium new_value')
    end
  end
end

<%= editable_input 'Year Founded', 'companyStartDate' %>

content_tag :div的代码块中,只会显示最后一个返回的字符串。


1
笔误(仅在注释中,但有点混淆)- “请注意这行中的‘+’” - Chowlett
加入这个后,我得到了语法错误:语法错误,意外的tIDENTIFIER,期望kDO或'{'或'(' text_field_tag name,'', :class => 'medium new_value' ^ - christo16
2
这感觉很不好...是因为一个帮助程序构建多个内容标签是一种反模式吗? - Erik Trautman
对我没用,不得不像其他答案建议的那样使用 concat - Dex

60

你也可以使用concat方法:

module InputHelper
  def editable_input(label,name)
    content_tag :div, :class => "field" do
      concat(content_tag(:label,label))
      concat(text_field_tag(name,'', :class => 'medium new_value'))
    end
  end
end

来源: 在Rails 3中嵌套content_tag


只要concat行在一行上,这对我很有效。不过,我没有花太多时间尝试它,所以可能有一种多行做法。 - TerryS
这将是一种更好的方式,考虑到html_safe问题。在非htmlsafe字符串之间使用+将使所有内容都变成非htmlsafe。 - Tian Chen
如果您在表单构建器类内部,应该使用@template.concat - elquimista
我认为这种方法比“+”更清晰。更易读,而且Rubocop不喜欢“+”。 - cercxtrova

4
我使用变量和连接来帮助更深层次的嵌套。
def billing_address customer
  state_line = content_tag :div do
    concat(
      content_tag(:span, customer.BillAddress_City) + ' ' +
      content_tag(:span, customer.BillAddress_State) + ' ' +
      content_tag(:span, customer.BillAddress_PostalCode)
    )
  end
  content_tag :div do
    concat(
      content_tag(:div, customer.BillAddress_Addr1) +
      content_tag(:div, customer.BillAddress_Addr2) +
      content_tag(:div, customer.BillAddress_Addr3) +
      content_tag(:div, customer.BillAddress_Addr4) +
      content_tag(:div, state_line) +
      content_tag(:div, customer.BillAddress_Country) +
      content_tag(:div, customer.BillAddress_Note)
    )
  end
end

2

使用迭代构建嵌套内容标签有些不同,这总是让我困扰...以下是一种方法:

      content_tag :div do
        friends.pluck(:firstname).map do |first| 
          concat( content_tag(:div, first, class: 'first') )
        end
      end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接