Conditionals and overriding - ruby-on-rails

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 %>

Related

get first 3 occurrence of an array

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.

Rails how to make conditional inside iteration?

i'm trying to use a conditional inside a iteration but did not worked so, here the scenario:
in this case if the if the order or the product is present should just show the order and products with the feedback.
but even if is present show the feedback with odata and pdata.
someone know why?
<% #feedbacks.each do |feedback| %>
<% if order.present? && product.present? %>
<% order = feedback.order %>
<% product = order.product %>
<% else %>
<% odata = feedback.odata %>
<% pdata = odata.pdata %>
<% end %>
I guess this is what you are trying to do,
<% #feedbacks.each do |feedback| %>
<% if (order = feedback.order).present? && (product = feedback.product).present? %>
<%= order.title %>
<%= product.title %>
<% else %>
<%= (odata = feedback.odata).name %>
<%= odata.pdata.name %>
<% end %>
<% end %>
Note: title and name are assumed columns, replace it with your required/respected attribute.
Please go through this to understand the difference between various erb tags.
Comparison:
for the if condition you are trying to call order and product directly, which will throw error as they are related to feedback.
<% %> just executes the ruby code, you wanted to print the data so need to use <%= %>.
no need to save them in variable when you are not going to use it. I have saved them while checking the existence of the object in the condition and could use to display without querying the db.

Dynamically displaying the column values

Here, I have 10 columns i.e., answer1, answer2, answer3, ..., answer10 in the table MgAnswer.
I have to check whether each column value is present or not. Only if it present,then I have to display it in the page.
Im giving column names dynamically within for loop
<% (1..10).each do |i| %>
<% if MgAnswer."answer#{i}".present? %>
<%= MgAnswer."answer#{i}" %>
<% end %>
<% end %>
Im ending up with Syntax error.
You can indeed dynamically invoke methods in ruby, but this is not the syntax. Instead do
<% (1..10).each do |i| %>
<% if MgAnswer.public_send("answer#{i}").present? %>
<%= MgAnswer.public_send("answer#{i}") %>
<% end %>
<% end %>
It should seem like the following:
<% (1..10).each do |i| %>
<%= MgAnswer.send("answer#{i}") %>
<% end %>
Since ruby can't evaluate line as MgAnswer."method". Also you can just skip if condition, because it will be evaluated to empty string "".

Rails. Check if ANY of the attributes in a collection is blank

I have a collection of invoices. One of the attributes is exchange_rate (is used to calculate the currency from US dollars for Mexican pesos). I need to create a warning if even ONE of the records doesn't have an exchange_rate set.
I could check if the exchange_rate of a record in a collection is blank like this...
<% is_blank = false %>
<% #invoices.each do |invoice| %>
<% if invoice.exchange_rate.blank? %>
<% is_blank = true %>
<% end %>
<% end %>
<% if is_blank %>
shoot warning: all of the invoices must have an exchange rate in order
to calculate pesos total
<% end %>
What is a more Railsy way of writing the above?
Simply like this, using the Enumerable#any? method:
<% if #invoices.any? { |i| i.exchange_rate.blank? } %>
shoot warning: all of the invoices must have an exchange rate in order
to calculate pesos total
<% end %>

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