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(", ")
Related
In my rails app I have iterate through discussions as below code.
<% #di.each do |d| %>
//my code goes here
<% end %>
This is my application_controller.rb
def load_feed_discussions(url:)
#c = session[:council] || ''
res = RestClient.get url, api_token_hash
#di = (JSON.parse(res.body) if res.code == 200)
rescue RestClient::ExceptionWithResponse
#di = nil
end
This is my discussion_controller.rb
def index
# Load Discussions
load_feed_discussions(url: api_version_root+'/discussions/all?council='+session[:council])
end
I want to sort discussion according to the 'updated_date'. How can I do this?
EDIT : here some sample data for #di
{"id"=>"609b966e-99f1-4606-ab8d-3c99ebb8dc9c", "question"=>"tttest body", "user_id"=>"609b966e-99f1-4606-ab8d-3c99ebb8dc9c", "score_model"=>nil, "council_id"=>"98bc626f-fbef-4b63-9cc9-4f1f2bad6b06", "created_at"=>"2020-04-22T11:41:51.503Z", "updated_date"=>"2020-06-29T03:06:49.155Z", "is_anonymous"=>false, "company_id"=>nil, "topics"=>nil, "was_edited"=>nil, "startup_id"=>nil, "recipients"=>[], "visibility_team"=>"default", "title_line"=>"tttest sub", "title"=>"Engineer", "company_logo"=>nil}
It depends heavily on what's #di; if it's an array of objects that respond to updated_date then you can use Enumerable#sort_by:
<% #di.sort_by(&:updated_date).each do |d| %>
...
<% end %>
If it's an ActiveRecord_Relation instance, you can use ActiveRecord::QueryMethods#order:
<% #di.order(:updated_date).each do |d| %>
...
<% end %>
The answer was none of the proposed ones, but sort_by { |e| e['updated_at'] }.reverse.
Assuming that #di is an array of responses, you can sort in descending date as follows in the controller...
def load_feed_discussions(url:)
#c = session[:council] || ''
res = RestClient.get url, api_token_hash
#di = [] # initialize to empty array in case of res.code != 200 or exception
#di = JSON.parse(res.body) if res.code == 200
rescue RestClient::ExceptionWithResponse
else
#di = #di.sort_by{|discussion| discussion['updated_date']}.reverse
end
It's not considered good practice to sort data in the view.
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 %>
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
I'm trying to get data out of this datamapper object and then putting it into a loop and getting the data out of the object that way, but it doesn't seem to be working, this is the code I have:
#user = User.get(session[:user])
#polls = []
polls = Poll.all(:user_id => #user)
polls.each do |poll|
pollname << poll.name
#polls << pollname
end
and in my erb file:
<% #polls.each do |poll| %>
<p><%= poll %></p>
<% end %>
I thinks what you want is:
#user = User.get(session[:user])
#polls = Poll.where(user_id: #user.id).all.collect { |p| p.name }
I've got two small structural issues that I'm not sure how to handle given my relative newbie-ness with RoR.
First issue: In one of my views, I have code that looks like this:
<ul style="list-style-type: circle">
<li><%= #apples.size %> apples</li>
<li><%= #oranges.size %> oranges</li>
<li><%= #bananas.size %> bananas</li>
<li><%= #grapefruits.size %> grapefruits</li>
</ul>
Is it possible to refactor this so that I only need to iterate once over some list of different kinds of fruit, and have the appropriate <li>'s be automatically generated? Edit: I forgot to add that #apples, #oranges, etc., might be nil. Is there an idiomatic way to handle that?
Second issue: In my controller, I have code that looks like this:
#apples = Apple.find(:all)
#apples.each { |apple| apple.do_stuff(:xyz) }
#bananas = Banana.find(:all)
#bananas.each = { |banana| banana.do_stuff(:xyz) }
# ... &c
As you can see, the same operation is invoked many times in exactly the same way. Is there a way to shorten this to something like [Apple.find(:all), ...].each { |fruit| ... } and have that work instead?
Thanks very much for your help!
I'd do this in a helper
def fruit_size(fruit)
list = #fruits[fruit]
return if list.empty?
content_tag(:li, "#{list.size} #{fruit}")
end
And this in the view:
<% ["apples", "oranges", "bananas", .....].each do |fruit| %>
<%= fruit_size(fruit)
<% end %>
In your controller:
#fruits = {}
["apples", "oranges", "bananas", ......].each do |fruit|
#fruits[fruit] = fruit.classify.constantize.find(:all).each {|record|
record.whatever_here
end
end
It makes sense to store all the items in a hash, #fruits, so that you don't have to use instance_variable_get and stuff.
Perhaps you also want to define that array somewhere, so that you don't have to repeat it in the controller and in the view. Let's pretend that you have a fruit model.
class Fruit < ActiveRecord::Base
FRUITS = ["apples", "oranges", "bananas", ....]
end
Then, use Fruit::FRUITS in the view and controller.
For the first part:
#li = ''
[#apples, #oranges, #bananas, #grapefruit].each{|fruit|
#li << "<li>#{fruit.size}</li>"}
<ul style="list-style-type: circle">
<%=#li%>
</ul>
You can actually do it pretty simply.
In your controller:
def whatever
#fruits = {
:apples => Apple.find(:all).each{ |a| a.do_stuff(:xyz) },
:bananas => Banana.find(:all).each{ |a| a.do_stuff(:xyz) } # ...
}
end
In your view:
<% #fruits.each |k, v| %>
<li><%= v.nil? ? 0 : v.size %> <%= k.to_s %></li>
<% end %>
Although you might want to consider whether do_stuff is something that could be done via a more complex finder, or by named scope.