【问题标题】:How will be the best way to render array of arrays in erb template?在 erb 模板中呈现数组数组的最佳方式是什么?
【发布时间】:2013-04-03 17:27:41
【问题描述】:

我有一个数组[["Company Name", "Field6"], ["Email", "Field5"]]

我正在从该数组中创建具有值的字段数组:

[
  [{:label=>"Company Name", :value=>"gfdgfd"}],
  [{:label=>"Email", :value=>"gfdgfd@gfd.pl"}]
]

使用

fields = [["Company Name", "Field6"], ["Email", "Field5"]]
# first element in array is Label and second is param id
fields_with_values = fields.collect do |field| 
 [
   label: field[0],
   value: params[field[1]]
 ]
end

然后我想将该标签和值传递给 erb 模板(类似):

# template.erb
<% fields_with_values.each do |field| %>
  l: <%= field.label %>
  v: <%= field.value %>
<% end %>

收集这些 fields_with_values 的最佳方式是什么?也许我应该使用 Object.new

【问题讨论】:

  • 你想达到什么目的?
  • 我想以清晰、简单的方式呈现这个template.erb
  • 你这样做有什么问题?
  • 我个人会避免在这种情况下实例化新对象,除非此处未提及的数据涉及某些业务逻辑。
  • +1 向导。对每个元素进行分类和实例化是一个不必要的步骤,其唯一目的是便于在视图中使用点表示法。

标签: ruby-on-rails ruby object sinatra erb


【解决方案1】:

最简单的最基本方法是:

class Foo
 attr_accessors :label, :value
 def initialize (label, value)
   @label = label
   @value = value
 end
end

fields_with_values = fields.map do |field|
   Foo.new(field[0], params[field[1]])
end

从这里开始,您可以使用 splat 运算符使其更加 Ruby 方式,或者动态创建对象等。

【讨论】:

    【解决方案2】:

    改为转换为哈希。

    fields = [["Company Name", "Field6"], ["Email", "Field5"]]
    
    fields_with_values = Hash[*fields.flatten]
    # => {"Company Name"=>"Field6", "Email"=>"Field5"}
    

    在你看来,解析散列:

    <% fields_with_values.each do |label, value| %>
      l: <%= label %>
      v: <%= params[value.intern] %>
    <% end %>
    

    请注意,如果您的输入数组不均匀,这将中断,即。没有值的键。


    编辑

    正如下面的评论 (+1) 中所述,重复键将不起作用。与另一个字段具有相同标签的字段是不好的。

    【讨论】:

    • 我喜欢这个!您只需要提到它不适用于重复标签(哈希键)。在这种情况下,这似乎不是问题。
    • 一件事:价值不是Field5而是params['Field5']
    • 已更新。我实习了value,它产生了一个符号(params[:Field5])。如果您想要一个字符串,请删除 .intern
    【解决方案3】:
    升: 五:

    我愿意

    fields_with_values = fields.collect do |field|
      {label: field[0], value: params[field[1]}
    end
    

    在视图中

    <% fields_with_values.each do |field| %>
      l: <%= field[:label] %>
      v: <%= field[:value] %>
    <% end %>
    

    但是,假设标签是一家公司,价值是一封电子邮件。如果你有类似的课程

    class Company < SomethingOrNothing
      attr_accessible :name, email
    
      # methods here
    end
    

    你可以的

    @companies = fields.collect do |field|
      Company.new(name: field[0], email: field[1]) 
    end
    

    然后

    <% @companies.each do |company| %>
      l: <%= comapny.name %>
      v: <%= company.email %>
    <% end %>
    

    但是,很可能为此创建一个新类是过度工程化的,除非您将在代码中一遍又一遍地使用这个类。

    【讨论】:

    • 好的,我明白了。我只会在这个模板中使用它。那么使用Struct 怎么样?
    • 好吧,不确定结构。我自己从未使用过它 - 我通常使用哈希或为它创建一个类。不确定使用 Struct 到底有什么优势。
    【解决方案4】:
    fields = [["Company Name", "Field6"], ["Email", "Field5"]]
    # first element in array is Label and second is param id
    
    fields_with_values = fields.collect do |label, param_id| 
      # It looks like there is no need for a nested array here, so just return a Hash
      {
        label: label,
        value: params[param_id]
      }
    end
    
    #=> [{:label=>"Company Name", :value=>"gfdgfd"}, {:label=>"Email", :value=>"gfdgfd@gfd.pl"}]
    

    看起来您正在尝试使用点语法从 Ruby 哈希中获取值,类似于您对 JavaScript 对象使用点语法(例如 field.label)。不幸的是,这不适用于 Ruby。我希望它这样做,因为它看起来很干净。对于 Ruby 哈希,您必须使用索引,在这种情况下是一个符号:field[:label]。您的 ERB 代码将如下所示:

    # template.erb
    <% fields_with_values.each do |field| %>
      l: <%= field[:label] %>
      v: <%= field[:value] %>
    <% end %>
    

    【讨论】:

      猜你喜欢
      • 2018-12-29
      • 1970-01-01
      • 1970-01-01
      • 2020-06-12
      • 1970-01-01
      • 2012-05-25
      • 2012-01-27
      • 2020-10-03
      • 2018-02-19
      相关资源
      最近更新 更多