HAML, Add class to image_tag - haml

I have
= image_tag "chart.jpg"
I am new to HAML so how do I add a class to this?

Assuming this is rails (Haml doesn't have its own image_tag helper, but Rails does), then the second argument is an options hash where you can specify the class:
=image_tag "chart.jpg", :class => "my_class"

Stumbled across this answer when I was looking for something else and thought I'd throw in a little update to use the more modern formatting :)
=image_tag 'chart.jpg', class: 'my_class'

Related

Correct way to share a view in the index page

I'm a Ruby-on-Rails newbie, just starting out.
I have an MVC called "account_types", generated via scaffold to produce:
controllers/account_types_controller.rb
helpers/account_types_helper.rb
models/account_type.rb
views/account_types/_form, edit, index etc...
Going to localhost:3000/account_types gives me the index view.
What I'd like to do is display the same data as selected from the account_types index method in the application index page as a list.
I wrote a new view called account_types/_list.html_erb as follows:
<ul>
<% #account_types.each do |account| %>
<li><% account.label %></li>
<% end %>
</ul>
I then edited home/index.html.erb (This is based on examples given in other questions on SO):
<%= render :partial => 'account_types/list', :module_types => #module_types %>
However I get
undefined method `each' for nil:NilClass
and the error displays the code from account_types/_list.html.erb where I've written
<% #account_types.each do |account| %>
The scaffolded views work fine, why aren't mine?
Are partials the right thing to use here?
Thanks in advance.
What is the correct way to define an application-wide partial and its variables in rails says to use a before_filter on ApplicationController.
You pass :module_types to partial, but use account_types. As I can see you just need to change your index.html.erb to:
<%= render :partial => 'account_types/list', :account_types => #module_types %>
You can use partials for this if you want, though it would be unnecessary in this case as far as I can tell (they are for sharing chunks of code between several views). In order to get this code to work you'll need to define #account_types in your controller with something like
#account_types = AccountType.all
You can see exact line in your account_types_controller.rb under index action. :module_types => #module_types is not necessary here, since I doubt you defined #module_types either and you don't use module_types in your partial at all.
It's obvious, that you don't understand how Rails works, so I suggest reading through a good tutorial (like this one) before you proceed with whatever you have in mind.

Rails STI Mystery - Why does type change from Class to String in view?

This is long so I hope you'll bear with me...
I have a model called Update with two subclasses, MrUpdate and TriggeredUpdate. Using single-table inheritance, added type field as a string to Update.
In my view I'm checking which type it is to decide what to display. I assumed since type is a string, I should do
<% if #update.type == 'MrUpdate' %>
This failed, i.e., it evaluated to false when the update was an MrUpdate. I noticed that at this point, #update.type.type is Class. OK, whatever, thought I, so I changed it to:
<% if #update.type == MrUpdate %>
and it worked, i.e., the comparison evaluated to true when the update was an MrUdpate. Then I did it again lower down in my view and it failed again (i.e., it evaluated to false when the update was an MrUpdate.)
Turns out the culprit is a couple of <%= link_to ... %> calls I use and make into buttons with jQuery. If I put this code in my view:
<br>
<%= #update.type.type %><br>
<%= #update.type %><br>
<%= link_to 'New Note', new_note_path(:update_id => #update.id), :class => "ui-button" %>
<br>
<%= #update.type.type %><br>
<%= #update.type %><br>
What I see is:
Class
MrUpdate
(the New Note button)
String
MrUpdate
It's changing from a class to a string! So what the heck am I doing wrong or missing here? Why should a link_to do that? First I'm not clear why it's not a string in the first place, but then really confused as to why it would change...?!? Any help or explanation would be helpful. I can just code it one way at the top and another way at the bottom, but that way madness lies. I need to understand why this is happening.
I figured out what the issue is here. Thanks to fl00r for pointing the way.
Yes, type is a reserved in Ruby 1.8.7 which tells you the class of the object you call it from. But it's also true that it is the name of the field used in Rails to indicate single-table inheriance and to store the name of the class of each instance of the subclass.
So I naively tried to access the value of the type field using #update.type. But what this was doing at the top of the view was calling the type method of the Object class in Ruby. For whatever reason, after the link_to calls, it was then access the value of the type field of the updates table.
While trying to figure this out I called #update.type in the Rails console and saw this message: "warning: Object#type is deprecated; use Object#class". Finally it registered what I was doing. When I changed my calls to:
<% if #update.class == MrUpdate %>
everything works as expected. I never saw a call to determine the type in any of the pages I found via Google about STI. This despite the fact that they all recommended using only one controller, wherein sometimes you must need to determine the class of the instance you have.
So, dumb mistake--pilot error. But maybe this will help someone else who gets tripped up on this.

Element class in Haml

I am using Haml in a Ruby on Rails project. I know you use the = sign to execute Ruby, but so far what I have seen is that the Ruby code has to be the last part of a line.
I am trying to add a class to a th element dynamically. (In case it's relevant: each td also contains more Ruby.)
I have the following code:
%th= link_to 'Name', res_path
I want to add a class to th, and the name of this class is in an instance variable called class_name. I tried this:
%th.=#class_name
But it doesn't work.
How should one include Ruby code twice on the same line using Haml?
The html_options solution offered by Alok will add the class to the 'a' tag. I would do this over two lines instead of one:
%th{ :class => #class_name }
= link_to 'Name', res_path
As #DavB pointed out, only static text can be used with the ./# notation. Otherwise, you can either pass your options to your helper method (if it accepts them), or, more universally, use a hash attribute as in %th{:class => #name}. It will result in <th class="namevalue">.
You could use the html_options of the link_to tag and then add the class there. I think thats the standard way of doing this.

Modify a URL helper for a path?

I have the following piece of code that I'm trying to fit into some generated scaffolding
= form_for(#event, :url => group_event_path(#event.group_id, #event) ) do |f|
As you can see, I've defined a nested resource route that looks like this
resources :groups do
resources :events
end
Now back to the form_for line above. The default Rails scaffolding uses code similar to above to generate _form, which is used in #new and #edit. The issue this presents to me is that form_for has to submit to these two paths
CREATE: group_events_path(#event.group_id)
UPDATE: group_event_path(#event.group_id, #event)
Is there a way for me to simplify this by modifying how the group_event(s)_path helpers work?
If you use the polymorphic form_for syntax, this will fix it:
= form_for([#group, #event]) do |f|
Now if that #event object is persisted in the database then it will use the update route, and if it's not then it will use the create route.
You can do the same thing with the normal form_for call:
= form_for(#event) do |f|
There's absolutely no reason to specify the :url option other than to customize the URL to be something different from what Rails infers.

Undefined method unexisting_url

I´m a newbie with Rails3 and I´ve got a strange problem. After searching in google and in StackOverflow for a while I decided to write down my question.
I have a Competencia and a Partida model. Competencia has_many :partidas and Partidas belongs_to :competencia.
I´m working with nested resources and my code looks like this:
routes.rb
resources :competencias do
resources :partidas
end
partidas_controller.rb
class PartidasController < ApplicationController
def new
#competencia = Competencia.find(params[:competencia_id])
#partida = #competencia.partidas.build
end
def create
#competencia = Competencia.find(params[:competencia_id])
#partida = #competencia.partidas.build(params[:partida])
if #partida.save then #blabla end
end
end
views/partidas/new.html.erb
<%= form_for [#competencia, #partida], :url => competencia_partidas_path(#competencia) do |f| %>
<!--blabla-->
<% end %>
I know that it isn´t the right way to specify the url in the form_for helper (specially if I´m not using a custom action), but it was the only way I could work it out. When I wrote something like this: <%= form_for [#competencia, #partida] do |f| %> I´ve got this error:
Showing /Users/ks/rails/projects/chronos/app/views/partidas/new.html.erb where line #4 raised:
undefined method `competencium_partidas_path' for #<#<Class:0x00000101718548>:0x00000101713728>
When I checked the routes (rake routes) everything seems to be fine.
competencia_partidas GET /competencias/:competencia_id/partidas(.:format) {:action=>"index", :controller=>"partidas"}
POST /competencias/:competencia_id/partidas(.:format) {:action=>"create", :controller=>"partidas"}
new_competencia_partida GET /competencias/:competencia_id/partidas/new(.:format) {:action=>"new", :controller=>"partidas"}
Can someone explain me where the competencium name comes from?. What would be the correct approach to solve this?
The problem is that Rails assumes english grammar rules for pluralization. You can read more here: http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html. You can customize the inflector or use English model names. I'm Italian and even when a project is meant only for Italian customer I prefer to use English names.
Rails tries to singularize you model name. In your case, it thinks competencia is the plural of a latin word. To add an exception, put the following in config/initializers/inflections.rb:
ActiveSupport::Inflector.inflections do |inflect|
inflect.singular "competencia", "competencia"
end