tomekfranek
tomekfranek

Reputation: 7099

How will be the best way to render array of arrays in erb template?

I have an array [["Company Name", "Field6"], ["Email", "Field5"]]

And from that array I am creating array of fields with values:

[
  [{:label=>"Company Name", :value=>"gfdgfd"}],
  [{:label=>"Email", :value=>"[email protected]"}]
]

using

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

and then I want to pass that labels and values to erb template(something like):

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

How will be the best way to collect these fields_with_values ? Maybe I should use Object.new

Upvotes: 3

Views: 3045

Answers (4)

gmaliar
gmaliar

Reputation: 5479

The easy most basic way would be:

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

from here on you can make it more Ruby way with splat operator or create the objects on the fly, etc. etc.

Upvotes: 1

Substantial
Substantial

Reputation: 6682

Convert to a hash instead.

fields = [["Company Name", "Field6"], ["Email", "Field5"]]

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

In your view, parse the hash:

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

Note that this will break if your input array is uneven, ie. a key without a value.


EDIT

As mentioned in a comment below (+1), duplicate keys will not work. Fields that have the same label as another field are no good.

Upvotes: 5

fotanus
fotanus

Reputation: 20116

l: v:

I would do

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

And in the view

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

However, lets say label is a company and value is an e-mail. If you have a class like

class Company < SomethingOrNothing
  attr_accessible :name, email

  # methods here
end

You could do

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

And then

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

However, most likely creating a new class just for that is over engineering, unless you will use this class over and over in your code.

Upvotes: 0

Wizard of Ogz
Wizard of Ogz

Reputation: 12643

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=>"[email protected]"}]

It looks like you are trying to use dot syntax to get values out of a Ruby Hash similar to how you would use dot syntax for a JavaScript object (e.g. field.label). Unfortunately this doesn't work for Ruby. I wish it did because it looks very clean. For the Ruby Hash you must use an index, which is a symbol in this case: field[:label]. Your ERB code will look something like this:

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

Upvotes: 2

Related Questions