Rails iteration over arrays and hashes - ruby-on-rails

I am trying to iterate over what I think is a hash in rails. I used deep_pluck gem to get the values of a Model including some values from the associations. Like this:
Continent.deep_pluck(:link_name, :name, 'countries' => [:link_name, :name])
this returns:
[{"link_name"=>"europe", "name"=>"europe", "countries"=>[{"link_name"=>"countryname", "name"=>"countryname"}]}]
I am trying to iterate this like this:
<% results.each do |continent| %>
<% continent.each do |link_name, name, countries| %>
<%= link_name %>
<% end %>
<% end %>
which in return this:
link_name
name
countries
I tried a lot of different ways and methods and I still can't get the desired output which is to print out the values of :link_name and :name and also another object of countries to iterate them over again for their name etc.
I'm trying to build a navigation menu which has a list of each continent with a submenu of the countries of the continent. I use pluck because I just want the names and link_names of the database.
Thank you very much!

When you iterate over a hash, you get access to the keys and values.
If you look at what's printing out, you're getting the keys of each hash. Your output might make more sense if you set the parameters to what they actually are.
<% results.each do |continent| %>
<% continent.each do |key, value| %>
<%= key %>
<% end %>
<% end %>
This should be enough to get you further along. To achieve what you want, you'll need to check each key and do something with the value based on what the key is.

Perhaps try something like:
[{"link_name"=>"europe", "name"=>"europe", "countries"=>[{"link_name"=>"countryname", "name"=>"countryname"}]}].each do |continent|
continent.each do |k,v|
case k
when 'countries'
v.each do |country|
country.each do |k,v|
puts " - #{v}"
end
end
else
puts v
end
end
end
(Naturally, you'll need to add the erb markup. And the "puts" are just for example to run this in console.)
Which will give you:
europe
europe
- countryname
- countryname

Thank you very much for your suggestions, i finally managed to make it work like this:
<% results.each do |continent| %>
<li class="has_children"><%= continent["name"] %>
<ul class="sub_menu">
<% continent["countries"].each do |country| %>
<li><%= country["name"] %>
<% end %>
</ul>
</li>
<% end %>

Related

Get model type from each loop

I'm combining two models in my controller, and trying to print them in a similar fashion, but I'd like to do an if statement in an each loop to distinguish one model from the other. My models are comments and likes.
In the controller:
#items = (#user.likes + #user.comments).sort{|a,b| a.created_at <=> b.created_at }
In my view:
<%= #items.each do |item| %>
<% item.name %>
<% end %>
I need an if statement to say IF comment or IF like in the each loop. I've been drawing a blank on the situation.
Assuming you have model Like and Comment
<%= #items.each do |item| %>
<% if item.instance_of?(Like) %>
Something for likes
<% elsif item.instance_of?(Comment) %>
Something for comments
<% end %>
<% end %>
You could do item.class.name as Nithin mentioned, and it'll work fine. However, the more idiomatic way is to use instance_of?. So it'd look like this:
if item.instance_of?(Post)
# do something
elsif item.instance_of?(User)
# do something else
end
Note you're not passing in 'Post' or 'User' as strings - you're passing in the Ruby class constants themselves.
On this topic, it's also worth knowing about Ruby's is_a? and kind_of? methods which work similar to instance_of? but return true if the instance you're testing is an instance of a subclass of the parameter you pass in (more info at Ruby: kind_of? vs. instance_of? vs. is_a?).
What you need to do is to check for the class of the Item of interest.
Basically, each object belongs to a class, and the class name of a comment will be a Comment while that of a like will be a Like.
So, in the loop, check for the class name as:
<%= #items.each do |item| %>
<% if item.class == Comment %>
...comments here
<% elsif item.class == Like %>
...likes here
<% end %>
<% end %>

Get list of unique column results from database

I've stumbled across this answer and it has helped me to generate a list of unique values exactly as I wanted, however, I don't want all of the results. Is there any way to filter the results within the select or another way to accomplish this?
I was thinking of something along the lines of this:
#results = MyModel.select("DISTINCT(columnForDistinction)", :myBoolean => false)
or
#results = MyModel.select("DISTINCT(columnForDistinction)", :someString => stringImLookingFor)
Currently, I'm not able to filter the results on the query, so I am iterating over the returned array and only listing the results that have that boolean set to false like so:
<% #results.each do |result| %>
<% if !result.myBoolean %>
#do stuff here
<% end %>
<% end %>
and
<% #results.each do |result| %>
<% if result.someString == stringImLookingFor %>
#do stuff here
<% end %>
<% end %>
Is there a better way to be doing this?
ActiveRecord query methods are chainable. You can call multiple and it will build them all into a query when you use the result. For conditions, you'll use where. Try something like:
#results = MyModel.select("DISTINCT(columnForDistinction)").where(:myBoolean => false)

How do I display specific key value pairs from a hash in the view?

I have a hash in my controller that a view takes data from to display. In the tutorials I've seen, I've learned how to display each of the key, value pairs from a hash...but how do I display only the key,value pairs I want?
creating the hash in the controller
#app = {'title' => title, 'description' => description,
'active' => active, 'featured'=> featured,
'partner'=>partner
}
view: this displays each of the key,value pairs
<% #app.each do |key, value| %>
<li><%= "#{key}: #{value}" %>
<% end %>
tried this in the view just to display title, but isn't working
<% #app.select do |ind_app| %>
<strong><%= ind_app["title"] %>
<% end %>
If you want to display the title, just ask for the title! No need to loop, you can directly access all values of a hash like this :
<strong><%= #app['title'] %></strong>
you can try to get the pairs you want first. Try the following
<% #app.slice('title', 'active').each do |key, value| %>
<li><%= "#{key}: #{value}" %>
<% end %>
This will only show the title and active part of the hash

Rails finding a value in a table

Is it possible to call the include? function on a whole table, like this?
<% #user.games.each do |g|
##latestround = g.rounds.order('created_at DESC').first
%>
<% if ##latestround.submittedpictures.isFinalPicture.include?(true) %>
<p>FinalPicture has been played!</p>
<% end %>
<% end %>
The problem i'm getting is that It only works when I put a block on submittedpictures and then loop through each record of this table. However I want to look through the whole table in one go and see if the column 'isFinalPicture' includes a value with 'false'.
Any ideas?
The following snippet works but its not the way i want it (I would get more lines if the round happens to have more 'true' FinalPictures)
<% ##latestround.submittedpictures.each do |s| %>
<% if s.isFinalPicture == true %>
<p>Final Picture has been played!</p>
<% end %>
<% end %>
You could make a scope for it like
class SubmitedPricture << ActiveRecord::Base
scope :final_pictures, where('isFinalPricture = ?', true)
end
then you could see if there is any with only one query
latestround.submittedpictures.final_pictures.any?
Also you should follow the conventions of Rails in naming your Models and everything else. Like submittedpictures should be submitted_pictures

What is the best way using multiple lines of <% %> Tag or <% %> Tag with multiple lines?

Sorry if the title is not enough to understand what i am asking about.
I am rails developer and i used multiple lines of <% %> in my views but now i realized that it's not best practice so i came here and like to you all excellent guys what is the correct way in ROR?
For example if i required to something like following
<% user =User.all %>
<% name= [] %>
<% count = 0 %>
<% for user in users %>
<% name << user.name %>
<% count+=1%>
<% end %>
Can i do it as follows ?
<% user =User.all
name= []
count = 0
for user in users
name << user.name
count+=1
end
%>
I know better way of collecting element from array But above is just example.
But my question is, is it possible and if yes which is the correct way?
I think the correct way is something totally different: move logic out of views.
This blog post explains what I mean.
in start and end must has '<%' or '%>'
Like:
<% users = User.all
name= []
count = 0
for user in users
count+=1
end %>
Using just a single pair of tags per code block is certainly preferable if only because it makes the output smaller.
The code should really rather look like
<% names = User.all.map(&:name) %>
Note that "count" can be obtained via names.size.
If you need to mix <% and <%= you need to switch:
<% for user in User.all %>
<%= user.name %></br>
<% end %>

Resources