Ternary operator not working in Haml - haml

This question has been asked but the answers have not worked. The problem I am having is this hamlc code:
.UI_feed_item.deletable.clearfix{ :class => #feed.fav_post ? 'favorited' : '', feed_id: "#{#feed.id}", id: "feed_item_#{#feed.id}" }
*a lot more haml that doesn't have to do with this question*
the indentation is correct - it shows up weird on here
I want an extra class added to say favorited if feed.fav_post is true. for some reason it added a class 'true' or 'false' instead. I have also tried this:
.UI_feed_item.deletable.clearfix{ :class => (#feed.fav_post ? 'favorited' : ''), feed_id: "#{#feed.id}", id: "feed_item_#{#feed.id}" }
same result
I cannot do an if/else thing because there is no end in haml and I would have to rewrite a hundred lines of indented code. please help! none of the other solutions on the web have worked

Your second shot should work fine. The first variant returns true/false because the hash rocket wins over the ternary operator in terms of precedence - but shouldn't it break on syntax error after that?
You can do if-else in haml.
- if true
some stuff here
- else
some other stuff here
Indentation is used instead of end.

HAMLC doesn't support the ?/: ternary operators, but you can still achieve what you want using inline if/then/else. Try this:
.UI_feed_item.deletable.clearfix{ :class => "#{ if #feed.fav_post then 'favorited' else '' }", feed_id: "#{#feed.id}", id: "feed_item_#{#feed.id}" }

Related

Why are ampersands escaped when generating url with link_to?

Here is my simple rails 3 code :
<%= link_to "link", gateway_index_url(developer:#item.developer.api_key, tracker:"email", url:#product.url) %>
And the result is :
<a href="/gateway?developer=abcde&tracker=email&url=http%3A%2F%2Fwww.bla.fr%2FproductA" >link</a>
The problem is that & are rewritten in &. I can't figure how to prevent escaping, as :escape => false doesn't exist in Rails 3
Update: So here's the source
def link_to(*args, &block)
if block_given?
options = args.first || {}
html_options = args.second
link_to(capture(&block), options, html_options)
else
name = args[0]
options = args[1] || {}
html_options = args[2]
html_options = convert_options_to_data_attributes(options, html_options)
url = url_for(options)
href = html_options['href']
tag_options = tag_options(html_options)
href_attr = "href=\"#{ERB::Util.html_escape(url)}\"" unless href
"<a #{href_attr}#{tag_options}>#{ERB::Util.html_escape(name || url)}</a>".html_safe
end
end
As we can see, from the source, this behavior is by design.
You can try one of two solutions, I haven't tried them but they should work
1.) Try placing the call to gateway inside of a call to #raw:
<%= link_to "link", raw(gateway_index_url(developer: #item.developer.api_key, tracker:"email", url:#product.url)) %>
That may solve your specific problem, an the second approach, while a bit more brute-force should also work...
2.) If you want to convert it (the whole href) back you can... use CGI::unescape_html:
<%= CGI::unescape_html(link_to "link", gateway_index_url(developer: #item.developer.api_key, tracker:"email", url:#product.url)) %>
Good luck, hopefully this helps.
Update 2: Fixed call to cgi unescape, was using "." when it should be "::" and formatting fix. Forgot to indent example for #1
Rory O'Kane is spot on. The answer to "Why are ampersands escaped when generating url with link_to?" is that is the correct way to separate params in a url.
Is there a problem with the url the way it is?
If so, could you elaborate on the problem?
You may be able to prevent escaping the url by using raw on the entire url like so:
<%= link_to "link", raw(gateway_index_url(developer:#item.developer.api_key, tracker:"email", url:#product.url)) %>

Rails - Simplify WHERE condition IS NOT NULL

Working on a webpage I used the next line:
Model.select(:column).where("column IS NOT NULL")
I was wondering if there was a more Rails-ish way to do this, like using a hash for example
Model.select(:column).where(column: !nil)
The Squeel gem will allow you to use != nil type syntax, but natively rails will not.
Example: Model.where{column != nil}
I would prefer to use a scope as its more readable as well as its more manageable later (like merging with other scopes)
class Model < ActiveRecord::Base
scope :not_null, lambda { |column|
{:select => column,
:conditions => "#{column} NOT NULL"
}
}
end
then use
Model.not_null("column_name")
In the Rails 4 you can do this:
Model.select(:column).where.not(column: nil)

Include? condition in haml view

I try to make something like this in haml view :
%li{:class => #taxon and ([#taxon] + #taxon.ancestors).include?(taxon) : "current"}
what the correct syntax ?
I'm guessing the value of #taxon is the class name? If so this should work for you.
- taxon_class = (#taxon && ([#taxon] + #taxon.ancestors).include?(taxon)) ? #taxon : "current"
%li{:class => taxon_class}
I always find it easier to do the ruby logic outside of the haml {} brackets.

Giving 'TemplateError' can't convert String into Integer

I recently transfered my app from Rails2 to Rails3.
The code in 'app/views/distribution/index.html.erb' is like :-
<div style="padding-bottom:10px; padding-left:0px;float:left;display:<%= (!session[:album][#artist.id.to_s].empty? && !session[:album][#artist.id.to_s].nil?)?'block' : 'none' %>" id = "make_payment_enabled">
<%= link_to 'Make Payments',{:action => 'pay', :album=>#album.id}, :class => "button" %>
</div>
It's giving me TemplateError on line :-
<div style="padding-bottom:10px; padding-left:0px;float:left;display:<%= (!session[:album][#artist.id.to_s].empty? && !session[:album][#artist.id.to_s].nil?)?'block' : 'none' %>" id = "make_payment_enabled">
How to resolve the problem ?
Solution 1: In the ERB tag, try putting spaces around the 'or' question mark, i.e. ....nil?) ? 'block....
Solution Better: Do step one, then put that code in a helper. Will really help to clean up your views.
UPDATE:
A few other tips: you will want to switch the order of the conditions, because you will want to see if the value is nil before checking if it's an empty string.
Calling obj.blank? is the equivalent of calling obj.nil? && obj.empty?, so that could make the code a bit shorter. Even better, obj.present? is the same as !obj.blank?.
Therefore, that line could be simplified to:
session[:album][#artist.id.to_s].present? ? 'block' : 'none'
Happy Rails-ing!

Is there a clean way to display a hyphen with haml

I have this partial that renders a line containing three peaces of data contained in a span, and between the spans there is a hyphen. Since the hyphen is a haml keyword (or whatever you call that) you can't just put it between the spans, or haml would go looking for a function or variable. So I've got this
%p
%span{ :class => 'client'}= "#{ won_or_lost['object']['deal']['client'] }"
= "-"
%span{ :class => 'value'}= "#{ won_or_lost['object']['deal']['value'] }"
= "- Thanks to"
%span{ :class => 'owner'}= "#{ won_or_lost['object']['deal']['owner'] }
You probably agree with me that
= "-"
is rather ugly. It's not a real problem, but is there a clean way to do this?
%p
%span.client= won_or_lost['object']['deal']['client']
\-
%span.value= won_or_lost['object']['deal']['value']
\- Thanks to
%span.owner= won_or_lost['object']['deal']['owner']
http://haml-lang.com/docs/yardoc/file.HAML_REFERENCE.html#escaping_
I sometimes prefer to use an Em-dash, which I think looks better typographically:
%p
%span.client= won_or_lost['object']['deal']['client']
—
%span.value= won_or_lost['object']['deal']['value']
— Thanks to
%span.owner= won_or_lost['object']['deal']['owner']