RAILS or in if statement - ruby-on-rails

I'm not sure how to use the OR in a view IF statement.
This doesn't work:
<% if current_user.employee.emptype.typename == "ADMIN" or "TECH" %>
Thanks!

Write something like this :
<% if current_user.employee.emptype.typename == "ADMIN" || current_user.employee.emptype.typename == "TECH" %>
Or better
<% if ['TECH', 'ADMIN'].include?(current_user.employee.emptype.typename) %>
Be careful with OR and AND keywords, they don't have same operators priority than && and ||

You can do this one of two ways. I prefer the first method.
<% if current_user.employee.emptype.typename.in?(["ADMIN", "TECH"]) %>
...or...
<% if current_user.employee.emptype.typename == "ADMIN" || current_user.employee.emptype.typename == "TECH" %>

That won't work, and it has nothing to do with views. In Ruby, all strings evaluate to true in if statements.
You have to check both values against the type name, like so:
if current_user.employee.emptype.type_name == "ADMIN" || current_user.employee.emptype.type_name == "TECH"
or check if it's contained within an array of valid types:
if ["ADMIN", "TECH"].include?(current_user.employee.emptype.type_name)
Please also see this article for a comparison of || and or in Ruby.

Related

If condition and Short circuit evaluation in rails - DRY

I m doing an app and I need to add multiple condition if. I want to know if an solution exist to DRY.
I m tried something like this but that dont work, it's like https://en.m.wikipedia.org/wiki/Short-circuit_evaluation
<% #camping.situations.each do |situation| %>
<%if situation.plage == "oui" || situation.etang == "oui" || situation.lac == "oui" %>
Do that
<%else%>
Do this
<%end%>
<%end%>
For my app to test more than 30 conditions so i dont want to repeat myself with multiple IF.
Example : Plage = oui / etang = Non / lac = oui
I want to display in my view :
Do that
Do this
Do that
Do you have any suggestions ?
EDIT
I m sorry i think my message wasn't clear. So for each entries I have 3 possible value 1) OUI 2) NON 3) EMPTY. User add the value of his object.
So in my view i display like this
<% #camping.caracteristiquetests.each do |caracteristiquetest| %>
<%if caracteristiquetest.animaux =="oui"%>animaux<%else%><s>animaux</s><%end%>
<%if caracteristiquetest.barbecue=="oui"%>barbecue<%else%><s>barbecue</s><%end%>
<%if caracteristiquetest.handicap =="oui"%>handicap<%else%><s>handicap</s><%end%>
<%if caracteristiquetest.piscine=="oui"%>piscine<%else%><s>piscine</s><%end%>
<%if caracteristiquetest.jeux =="oui"%>jeux<%else%><s>jeux</s><%end%>
<%if caracteristiquetest.loisir=="oui"%>loisir<%else%><s>loisir</s><%end%>
<%end%>
<!--Affiche les parametres de la table situation-->
<% #camping.situations.each do |situation| %>
<%if situation.plage =="oui"%>plage<%else%><s>plage</s><%end%>
<%if situation.etang =="oui"%>etang<%else%><s>etang</s><%end%>
<%if situation.montagne =="oui"%>montagne<%else%><s>montagne</s><%end%>
<%if situation.riviere =="oui"%>riviere<%else%><s>riviere</s><%end%>
<%if situation.foret=="oui"%>foret<%else%><s>foret</s><%end%>
<%end%>
If value is different to "oui" my view show Strikethrough.
I have more entries but it's always the same condition. As you can see i have lot of "IF". So i just wanna know if it's possible to DRY this ?
You could do it as follows.
The code situation.members.any?{|m| situation.send(m) == 'oui'} enumerates the members (attributes) of your situation object and compares the value of them each by doing a send of the membername against the string 'oui', if any of them contains it the whole expression is true.
The ternary statement ? evaluates this and puts the "Do that" if true and the "Do this" else.
situation = Struct.new(:plage, :etang, :lac)
situations = []
situations << situation.new('non','oui','non')
situations << situation.new('non','non','non')
situations.each do |situation|
puts situation.members.any?{|m| situation.send(m) == 'oui'} ? "Do that" : "Do this"
end
# gives
# Do that
# Do this
If I understand your last edit correct, this would become
situations.each do |situation|
situation.members.each{|member| puts situation.send(member) == 'oui' ? "Do that" : "Do this"}
end
You really should make your question more clear next time.
Based on your last edit, my last attempt, you just need to go one level deeper.
We just give you the methods how to do something, the rest is up to you.
More Dry than this it won't become..
camping = Struct.new(:situation, :caracteristiquetest)
campings = []
situation = Struct.new(:plage, :etang, :lac, :montagne, :riviere, :foret)
caracteristiquetest = Struct.new(:animaux, :barbecue, :handicap, :piscine, :jeux, :loisir)
campings <<
camping.new(situation.new('non','oui','non','non','oui','non'),
caracteristiquetest.new('non','oui','non','non','oui','non'))
campings <<
camping.new(situation.new('oui','oui','non','non','oui','non'),
caracteristiquetest.new('non','oui','non','non','non','non'))
campings.each do |camping|
camping.members.each do |camping_attr|
camping.send(camping_attr).members.each{|member|
puts camping.send(camping_attr).send(member) == 'oui' ? member : "<s>#{member}</s>"
}
end
end
Which gives
<s>plage</s>
etang
<s>lac</s>
<s>montagne</s>
riviere
<s>foret</s>
<s>animaux</s>
barbecue
<s>handicap</s>
<s>piscine</s>
jeux
<s>loisir</s>
plage
etang
<s>lac</s>
<s>montagne</s>
riviere
<s>foret</s>
<s>animaux</s>
barbecue
<s>handicap</s>
<s>piscine</s>
<s>jeux</s>
<s>loisir</s>

Can you use dirty attributes methods with current_user in rails?

I am trying to detect whether a user changes there first name or last name. I was wondering if you can use current_user with dirty attributes? I was thinking along the lines of
<% if current_user.first_name.changed? == true || current_user.last_name.changed? == true %>
<h4>Name Changed</h4>
<% end %>
I get this error
undefined method `changed?' for "john":String
Does anyone know of a way of doing this? might be missing something obvious. Thanks
-John
Not .changed?,it is _changed?
<% if current_user.first_name_changed? == true || current_user.last_name_changed? == true %>
<h4>Name Changed</h4>
<% end %>
See here

Add a selected class to links depending on id

My question is very similar to this one : Changing Current Tab in Rails
I am trying to add a 'selected' class to my link regarding the id of my portfolios controller’s show action
Here is what I've tried:
<ul>
<% for portfolio in #portfolios %>
<li class="<%= controller.class == PortfoliosController and controller.action_name == 'show' and controller.params[:id] == portfolio.id ? 'selected' : '' %>"><%= link_to portfolio.name, portfolio %></li>
<% end %>
</ul>
But it seems that the following:
controller.params[:id] == portfolio.id
doesn't match correctly and I don't understand why..
Thanks for your help!
Beware: params are always strings.
So :
controller.params[:id].to_i == portfolio.id
SideNote: extract this kind of logic in helpers, it's much cleaner.
You might be comparing string and numerical values, which in Ruby are not considered equivalent. A conversion of one of or the other might help. In fact, if you roll this up in a helper method, it might make it a lot easier to follow:
def class_for_porfolio_entry(portfolio)
controller.class == PortfoliosController and
controller.action_name == 'show' and
controller.params[:id].to_i == portfolio.id ?
'selected' :
''
end
You've got a whole lot going on there, so you might want to look at ways of reducing the complexity, for instance using params instead:
def class_for_porfolio_entry(portfolio)
params[:controller] == 'portfolios' and
params[:action] == 'show' and
params[:id].to_i == portfolio.id ?
'selected' :
''
end
This could be simplified further if you had a boolean flag set in your controller that is later used as required, avoiding hard-coding something like this:
def class_for_porfolio_entry(portfolio)
if (#show_selected_portfolio and #portfolio.id == portfolio.id)
'selected'
else
''
end
end
This presumes you have an instance variable #portfolio, which is usually the case in any controller's show method, and that you will set #show_selected_portfolio to true in any controller method where this logic applies.

ruby, how to structure an if block with AND & OR

Right now I have the following:
<% if !#thread.nil? && #thread.name == 'X' || #thread.name == 'Y' %>
....
The problem here is that I believe regardless if !#thread.nil?, #thread.name is still be called which is causing errors.
What's the right way to write this so it's like:
<% if !#thread.nil? && #thread.name == ('X' || 'Y') %>
Some type of contained in a list? for the thread.name?
Thanks
if !#thread.nil? && ['x','Y'].include?(#thread.name)
if #thread.present? and ['X', 'Y'].include?(#thread.name)
Edit: More info on #present?.
The try method could make this code more clearer. Take a look at this http://everydayrails.com/2011/04/28/rails-try-method.html.
['x', 'Y'].include?(#thread.try(:name))
or
['x', 'Y'].include? #thread.try :name

A blank? version for database fields which has 0 oder NULL?

in my database I have a field which holds foreign keys. Sometimes the values are NULL or 0.
I know the helper blank?. Is there something similar to enable if there is a number set in the field? Because blank doesn't work here.
the code for the view is something like this
<%= #b.author unless #b.author_id.blank? %>
you could write your own helper
def identified? author
author.id.blank? or author.id == 0
end
You could try something like:
<% if #b.author_id == 0 %>
#display something here
<% else %>
#display something else
<% end %>
in your view.

Resources