This is the array of hashes received as parsed_response from an API response which was XML, using Httparty.
Difficult and confusing to traverse inside and get the value.
"flights"=>{
"flight"=>{
"segments"=>{
"segment"=>[ (this has square brackets)
{
"index"=>"3",
"departure_airport"=>"DEL",
"arrival_airport"=>"CCU",
"departure_date_time"=>"2014-07-07T13:20:00",
"arrival_date_time"=>"2014-07-07T15:35:00",
"flight_number"=>"20",
"airline"=>"AI",
"operating_airline"=>"AI",
"stops"=>"0",
"equipment"=>"320",
"duration"=>"8100"
},
{
"index"=>"4",
"departure_airport"=>"CCU",
"arrival_airport"=>"BLR",
"departure_date_time"=>"2014-07-07T18:10:00",
"arrival_date_time"=>"2014-07-07T20:40:00",
"flight_number"=>"771",
"airline"=>"AI",
"operating_airline"=>"AI",
"stops"=>"0",
"equipment"=>"319",
"duration"=>"9000"
}
]
}
}
},
To display above hash values I did
<% h["flights"]["flight"]["segments"]["segment"].each do |o,p| %>
<% if o.class == Hash %>
<strong><%= o['airline'] %></strong>
<%= o['arrival_airport'] %> - <%= o['arrival_date_time'] %><br>
<% else %>
<%= o %>
<% end %>
<% end %>
(NOTE: Simply placing o['airline'] after loop would give can't convert String into Integer)
The else statement is to parse the below type of response.
"flights"=>{
"flight"=>{
"segments"=>{
"segment"=>{ (no square brackets)
"index"=>"3",
"departure_airport"=>"DEL",
"arrival_airport"=>"CCU",
"departure_date_time"=>"2014-07-07T13:20:00",
"arrival_date_time"=>"2014-07-07T15:35:00",
"flight_number"=>"20",
"airline"=>"AI",
"operating_airline"=>"AI",
"stops"=>"0",
"equipment"=>"320",
"duration"=>"8100"
}
}
}
},
So having <%= o %> after else statment, will give
["index", "7"] ["departure_airport", "DEL"] ["arrival_airport", "BLR"] ["departure_date_time", "2014-07-10T07:10:00"] ["arrival_date_time", "2014-07-10T09:50:00"] ["flight_number", "807"] ["airline", "9W"] ["operating_airline", "9W"] ["stops", "0"] ["equipment", "738"] ["duration", "9600"]
But having <% elsif o=="departure_airport" %> <%= p %> <% end %> in-place of else statement, will give the value associated with the key.
To get a single value using the key, this is fine. But it really gets messy to put all those key in the above format to get their values.
There should be a better way to parse it, but just cant figure out how will I deduce a use case where ['segment'] would give the result appropriately, based on if it is again a hash or it is just a key.
Thanks.
The solution here would be to wrap the Hash into an Array before looping it.
controller
#segments_array = Array.wrap(h["flights"]["flight"]["segments"]["segment"])
view
<% #segments_array.each do |segment| %>
<strong><%= segment['airline'] %></strong>
<%= segment['arrival_airport'] %> - <%= segment['arrival_date_time'] %><br>
...
<% end %>
[h["flights"]["flight"]["segments"]["segment"]].flatten.each do |segment|
puts "#{segment['arrival_airport']} - #{segment['arrival_date_time']}"
end
HTH
Related
_form.html.erb
<% #subjectmodulelists.each_with_index do |modules,index| %>
<%= hidden_field_tag 'subjectModuleId'+index.to_s, modules.subject_module_id%><%= f.submit class:"btn btn-primary" %>
<% end %>
The above code I have in partial form actual field name was subject_module_id in my db. Here i changed to 'subjectModuleId'+index.to_s for store array of data.
I have following Error.
Mysql2::Error: Field 'subject_module_id' doesn't have a default value: INSERT INTO term_questions
Params passes Like:
"subjectModuleId0"=>"65", "subjectModuleId1"=>"66", "subjectModuleId2"=>"67",
In my controller
#question = TermQuestion.new
#question.subject_module_id = params[:subjectModuleId]
How I change the name into subject_module_id.
Thanks.
Pass array value to the hidden field
<%= hidden_field_tag 'subject_module_id[]', #subjectmodulelists.map(&:subject_module_id) %>
<%= f.submit class:"btn btn-primary" %>
This way you will get params like
{ "subject_module_id"=>[65, 66, 67] }
Which then you can assign
#question.subject_module_id = params[:subject_module_id]
I got four different models.
Here's an example,
#single = Single.all
#coe = Coe.all
#blend = Blend.all
#production = #single+#coe+#blend
then how to check which model #production is?
I tried
<% #production.each do |p| %>
<%=p.class.name%>
<% end %>
but it returns "Array"
It seems to be simple, but I can't find out
(I edited question)
The problem is here
#single = Single.all
#coe = Coe.all
#blend = Blend.all
#production = #single+#coe+#blend
change these lines with
#single = Single.all.to_a
#coe = Coe.all.to_a
#blend = Blend.all.to_a
#production = #single+#coe+#blend
and then if you will check
#production.first.class.name #Single
#production.last.class.name #Blend
so in your view you can do this
<% #production.each do |p| %>
<% p.each do |product| %>
<%= product.class.name %>
<% end %>
<% end %>
if while iterating on #production it returns array so you need to try this.
<% #production.each do |p| %>
<% p.each do |product| %>
<%= product.class.name %>
<% end %>
<% end %>
#production is a collections of combinations of single, coe, and blend thats why #production.class.name doesnt work, you need to iterate each object like this:
<% #production.each do |object| %>
<%= object.class.name %>
<% end %>
I am getting this error that I have never seen before
can't convert Symbol into Integer
model:
#customers = [
{
:customer_name => 'James',
:group_name => 'Latin# Social Work Coalition',
}
html.erb
<div id="group_name" class="group-name">
<h1>
<%= #customers[:group_name] %>
</h1>
</div>
#customers is an array
<div id="group_name" class="group-name">
<h1>
<%= #customers.first[:group_name] %> #or #customers[0][:group_name]
</h1>
</div>
#customers is being declared as an array, which is indexed by integer, but you are passing in a symbol.
If you're looking to find a customer by :group_name
<%= #customers.detect { |customer| customer[:group_name] == <GROUP_WANTED> } %>
This is a very beginner question, but I've searched and can't find anything. I'm attempting to loop through an object, then store the information in an array (or object?) so that I can spit out a string of the items.
<% #da = [] %>
<% #report.data_items.each do |di| %>
<% if di.status == "Complete" %>
<% #da += di.url_metric.da %> #not sure how to append to the end of the array
<% end %>
<% end %>
Help? Should I use an array or object?
Seems that you're doing this in ERB template for some reason. Don't. Keep templates clear and simple. Do this kind of calculations in controller.
Here's a better version:
#da = #report.data_items.select {|di| di.status == 'Complete'}.
map{|di| di.url_metric.da }
#da = #report.data_items.collect{|di| di.url_metric.da if di.status == "Complete"}.compact
Here's shorted varian of what you're trying to accomplish:
#da = #report.data_items.select do |item|
item.status == "Complete"
end.map { |item| item.url_metric.da }.join(", ")
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=>"gfdgfd#gfd.pl"}]
]
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
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.
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"}]
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 %>
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.
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.