get first 3 occurrence of an array - ruby-on-rails

In my rails app I have below code to print some data from database.
<% #di.each do |d| %>
<% if d["visibility_team"] == 'for_all' %>
//my code goes here
<% end %>
<% end %>
I just want to print first 3 occurrence which fulfill the d["visibility_team"] == 'for_all' condition.
How can I do this?

If you can't get #di as 3 records from DB, how about keeping counter how many ds were printed?
Something like this (feel free to style it the way you want)
<% counter = 0 %>
<% #di.each do |d| %>
<% if d["visibility_team"] == 'for_all' %>
<% counter += 1 %>
<% break if counter == 3 %>
//your code goes here
<% end %>
<% end %>
However it's usually a bad taste to have so much logic in views.

Related

Ruby is adding weird spacing between words

My website is printing out elements such as (SnO), however, it should be printing SnO, but it is adding a weird space and it is printing like Sn O. It is adding a space between the element for no reason. My code is on the listed below.
<% saved_element = ""%>
<% sensor.base_material.elests.each_with_index do |elest, v| %>
<% if elest.element.include? "O" %>
<% saved_element = elest %>
<% else %>
<%=elest.element.split('-').last %>
<% if elest.stoich != 1 %>
<sub><%=elest.stoich.to_i%></sub>
<% end %>
<% end %>
<% if v == sensor.base_material.elests.length-1 %>
<%=saved_element.element.split('-').last%>
<% if saved_element.stoich != 1 %>
<sub><%=saved_element.stoich.to_i %></sub>
<% end %>
<% end %>
<% end %>
The code you show is full of white spaces (at the beginning of each line). Those are printed on the HTML and compacted as one space. Also, when you print a value, it adds an space at the end, you can supress that usign <%= ... -%> (note the dash at the end)
https://www.howtobuildsoftware.com/index.php/how-do/Nzr/ruby-on-rails-erb-suppressing-spaces-in-erb-template
Anyway, I would move all that logic to a helper method, that's what helper methods are for.

Conditionals and overriding

I'm using a conditional to check if two values exists. I want to override the first conditional with the second one. Most likely if the second one exists then the first will, if that makes sense. Not the issue i'm having is using two different call methods.
What I have so far:
<% #data.each do |i| %>
<% if i.stock.present? %>
In Stock
<% elsif i.sold.present? %>
Sold
<% else %>
n/a
<% end %>
<% end %>
So, if in stock display 'In Stock', if sold display 'Sold'.
I think I have a solution, but feel free to let me know if there is a better way. This is using the unless statement and seems to display what I need.
<% #data.each do |i| %>
<% unless i.stock.present? %>
In Stock
<% else if i.sold.present? %>
Sold
<% else %>
n/a
<% end %>
<% end %>
<% end %>

Insert between array in rails .each while loop

I have 100 shoes with shoe names. I don't want to display all 100 in a row, I want to display 5, then a green box, then the next 5, and the same green box... but there is something wrong with my code.
<% #shoes.each.with_index(1) do |shoe, index| %>
<% while index < 101 do %>
<%= shoe.name %>
<% if index % 5 == 0 %>
<%= Green Box %>
<% end %>
You're looking for in_groups_of(x)
<% #shoes.in_groups_of(5) do |shoe_groups| %>
<% shoe_groups.each do |shoe| %>
<%= shoe.name %>
<% end %>
<%= 'Green Box' if shoe_groups.size % 5 == 0 %>
<% end %>
Your syntax is wrong in several places - the enumerator is wrong, you are missing several end statements. Also, even though index is not a reserved word, the generally accepted style for an index is a single-letter variable like i. It should be
<% #shoes.each_with_index(1) do |shoe, i| %>
<% while i < 101 do %>
<%= shoe.name %>
<% if i % 5 == 0 %>
<%= Green Box %>
<% end %>
<% end %>
<% end %>
(But personally, I would not do the index < 101 block in the view - I would make sure that the controller that generates #shoes and sends it to the view only sends 100 elements in the array)

How can I loop through and Save values into an array

The following loop goes through the sales column and lists all 4 existing product values, like 19.99 19.99 3.99 3.99 to the corresponding user id.
<% #sales.each_with_index do |sale, index| %>
<% if current_user.id == sale.user_id %>
<% price = Warehouse.where(:product => sale.product).pluck(:mrr) %>
<%= value = price.split(',').join('.').to_f %>
<% else %>
<% end %>
Now I want to save the results/values into a new global variable and add up each out of "value". So the result of 19.99 19.99 3.99 3.99 should be 47.96.
I'm completely lost. Any Ideas?
You could do something like this:
<% total = 0 %>
<% #sales.each_with_index do |sale, index| %>
<% if current_user.id == sale.user_id %>
<% price = Warehouse.where(:product => sale.product).pluck(:mrr) %>
<%= value = price.split(',').join('.').to_f %>
<% total += value %>
<% end %>
<% end %>
<%= "Total is #{total}" %>
It is highly questionable to have code like this in the view though. You could get prices and calculate totals in your controller instead.
Also note that you are missing an end. I changed the unneeded else to an end.
In your controller you can create a instant variable prefixed by # so it can be used throughout your view
For example in your controller
#total_value = 0
And in your view
<%#sales.each_with_index do |sale, index| %>
<% if current_user.id == sale.user_id %>
<% price = Warehouse.where(:product => sale.product).pluck(:mrr) %>
<%= value = price.split(',').join('.').to_f %>
<% #total_value += value %>
<% else %>
<% end %>
You shouldn't add that kind of logic in your view. Create a view object class (that the controller instantiates) too handle all of this. You also probably can do something like:
user.sales.each do |sale|
total += find_price(sale)
# do more stuff
end
If you are asking 'if current_user.id == sale.user_id' then you most likely doing it wrong.
In that view object you could have a hash that has all the prices you want to show and iterate over that in your view.

How to reduce number of hierarchical 'if statements'

I have hierarchical the statements like this
<% #descriptions.each_with_index do |description, i| %>
<% description.tale2.each do |tax_ref| %>
<% if condition %>
<% if condition %>
<% if condition %>
<%= $text_first_describe%> <%= $paren_author_yr %>
<% ref_sp_uniq.each_with_index do |ref, i| %>
<% if ref == tax_ref.ref_wo_brace%>
<% execution %>
<% elsif i == (ref_sp_uniq.size - 1)%>
<%# #ref_desc = "#{#ref_desc_numb}. #{tax_ref.ref_wo_brace}" %>
<% end %>
<% end %>
<% if condition %>
<% execution %>
<% elsif condition %>
<% execution %>
<% elsif taxon_name.emend_author_year %>
<%= print %>
<% else %>
<%= print %>
<% end %>
<% end %>
<% else %>
<% if condition %>
<%= print %>
<% ref_sp_uniq.each_with_index do |ref, i| %>
<% if condition %>
<% execution %>
<% elsif condition %>
<% execution %>
<% end %>
<% end %>
<% if condition %>
<% execution %>
<% elsif condition %>
<% execution %>
<% elsif condition %>
<% execution %>
<% else %>
<% execution %>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
Kindly suggest me possible way to reduce this kind of junk "if statements".
If your nested IFs are becoming very complex, you might consider describing the entire structure with a state machine and processing it like that. That way you get the documentation of the formal state diagram and your code will be much simpler.
Edit:
Here is a better attempt to describe the process. The nice thing about
this is that once you have your initial state diagram and the code to
process it, adding new states is very easy to do. (Expecially if you
build a little tool to read your diagram and generate your table for
you).
Most people just use these in the context of regular expressions and
leave them alone otherwise, but it is a nice powerful tool to have in
your toolbox. A common example is implementing a full ftp server this
way is trivially easy.
Ok, to my better example, hope this helps.
Consider this IF psuedo code:
if (a < 5)
do_b
do_c
if (a < 3)
do_d
else
do_e
end-if
end-if
The state transition table to process this might look like:
State Transition Action Next state
----- ---------- ------ -----
1 a < 5 2
1 7
2 do_b 3
3 do_c 4
4 a < 3 5
4 6
5 do_d 7
6 do_e 7
7 exit
The code to process it would look like this:
currentState = 1
foreach table entry
if table_state == currentState
&& table_transition is true or blank
call table_action
currentState = table_next_state
Take a look at http://en.wikipedia.org/wiki/State_transition_table for a
more formal description.
first of all I would put this code in a helper, so you get rid of all the tags and you clean the view, then look if you can apply the case statement and latter remember maybe you can include line_of_code if condition or condition ? code_a : code_b.
Hard to do something without conditions (I suppose the condition change each if), why not to address the question to https://codereview.stackexchange.com/
?
Ruby's case syntax would probably be a good starting point for cleaning that up, but like others have mentioned you probably need to rethink whats going on in there. Ultimately you probably want to be moving as much of that logic into the model as you can.
My two cents.

Resources