Notes posted to Ruby on Rails
RSS feedHTML5 data- attributes using RESTful approach
HTML5 specifies extensible attributes like data-foo=“bar” (or as in Twitter Bootstrap data-toggle=“modal”), which poses two problems for Rails.
First, if you’re using symbol notation in link_to to specify attributes, this fails (dash is not a valid symbol character), so
Invalid!
link_to "Edit", @user, :class => "btn", :data-toggle => "modal"
There are two solutions:
-
put the symbols in quotes,
-
use the special :data hash
Solution 1: Quote Symbols
link_to "Edit", @user, :class => "btn", "data-toggle" => "modal"
Solution 2: Use the :data hash
link_to "Edit", @user, :class => "btn", :data => {:toggle => "modal"}
Resulting HTML
<a href="/users/1" class="btn", data-toggle="modal">Edit</a>
The second is minimally documented, but as a hash, can accept multiple values and is perhaps a little cleaner
I got it
Perfect match to work with attr_accessible
Locale
To change default locale by the parameter you can set :locale option, like below:
select_date 'user', 'birth', :locale => 'de'
Missed close tag
At the page http://apidock.com/rails/ActionView/Helpers/TagHelper/tag
<tt>.data()</tt> should be instead of <tt>.data()<tt>
Looks like this method has trouble with attributes:
ex:
require 'rubygems' require 'bundler' require 'active_support/core_ext' require 'pp' xml = '<test id="appears"> <comment id="doesnt appear"> it worked </comment> <comment> see! </comment> <comment /> </test>' hash = Hash.from_xml(xml) pp hash #=>{"test"=>{"id"=>"appears", "comment"=>["it worked", "see!", nil]}} # Notice how the id attribute on the first comment element doesn't appear.
Options select_hour
In my view I wanted to do this <%= select_hour(@hour, :start => 8, :end => 12) %> but did not work. I looked at the documentation and have not seen anything like it. http://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html#method-i-select_hour
So I studied how it worked this helper. http://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html#method-i-select_hour develop and achieve this:
the helper application:
module DataAnnouncementsHelper
class HelperDate < ActionView::Helpers::DateTimeSelector def select_hour if @options[:use_hidden] || @options[:discard_hour] build_hidden(:hour, hour) else build_options_and_select(:hour, hour, :end => @options[:end], :start => @options[:start], :ampm => @options[:ampm]) end end end def select_hour(datetime, options = {}, html_options = {}) HelperData.new(datetime, options, html_options).select_hour end
end
The view:
<%= select_hour(@hour, :start => 8, :end => 12) %>
Where @hour = 10 the result is:
<select id=“date_hour” name=“date[hour]”>
<option value="08">08</option> <option value="09">09</option> <option value="10" selected="selected">10</option> <option value="11">11</option> <option value="12">12</option>
</select>
JQuery script for dynamically adding and removing fields_for
I like drogus idea. But I wanted a cleaner one, so I created an unobtrusive JQuery script to have the same functionality.
Example Usage:
<%= form_for @post do |form| %> Title: <%= form.text_field :title %> Body: <%= form.text_field :body %> Tags: <div id="tag-list"></div> <div class="numerous"> <div class="numerous-form"> <%= form.fields_for :tag, Tag.new, :child_index => "replace_this" do |f| %> <%= f.text_field :name %> <%= f.hidden_field :_destroy, :value => 0, :class => "numerous-remove-field" %> <%= link_to "delete", "#", :class => "numerous-remove" %> <% end %> </div> <%= link_to "add tag", "#", :class => "numerous-add", :id => "for-tag-list" %> </div> <% end %>
See script at: http://github.com/kbparagua/numerous.js
Disable layout on ajax
In actions that may or may not be loaded via ajax I use:
render :layout => !request.xhr?
For an entire controller I might use something like:
layout :has_layout? private def has_layout? request.xhr? ? false : controller_name end
What seems unusual is that
layout true
will try look for the layout true.erb
Replaced by
replaced by “class_attibute”: http://apidock.com/rails/v3.2.1/Class/class_attribute
Replaced by
replaced by “class_attibute”: http://apidock.com/rails/v3.2.1/Class/class_attribute
Makes it possible to use a scope through an association
This is a very useful method if you want to to use a scope through an association:
class Book < ActiveRecord::Base scope :available, where(:available => true) end class Author < ActiveRecord::Base has_many :books scope :with_available_books, joins(:books).merge(Book.available) end # Return all authors with at least one available book: Author.with_available_books
See http://asciicasts.com/episodes/215-advanced-queries-in-rails-3 for more info.
Example to auto download
Controller
op = Operation.find(params[:id]) fname = "operation_#{op.id}_#{DateTime.now.to_i}.csv" send_data op.export(params[:url_type]), :type => 'text/csv; charset=iso-8859-1; header=present', :disposition => "attachment; filename=#{fname}.csv"
export_csv
def export(url_type) csv_data = CSV.generate do |csv| csv << self.header_columns # simple array ["id","name"] url_items = @operation.url_items.where(:url_type => url_type) url_items.each do |url_item| csv << self.process_row(url_item) # simple array [1,"bob"] end end return csv_data end
Use exist scopes on default_scope - pay attention
To use exists scopes on default_scope , you can use something like:
class Article < ActiveRecord::Base scope :active, proc { where("expires_at IS NULL or expires_at > '#{Time.now}'") } scope :by_newest, order("created_at DESC") default_scope by_newest end
But, if you would add a filter, and it require a lazy evaluate, use block on default_scope declaration, like:
default_scope { active.by_newest }
Deprecation in 3.1+
In Rails 3.1 and higher, just use ruby’s SecureRandom, e.g.
Before
ActiveSupport::SecureRandom.hex
After
SecureRandom.hex
Deprecated proxy_owner
Just change your
proxy_owner
calls to
@association.owner
Found it here: http://mileszs.com/deprecation-warnings-for-proxyowner-in-rails
Add html5 scriipt async attribute
http://www.w3schools.com/html5/att_script_async.asp
javascript_include_tag "application", :async => true
flash messages
In rails 3.1 the following does not work for me
redirect_to { :action=>'atom' }, :alert => "Something serious happened"
Instead, you need to use the following syntax (wrap with parens)
redirect_to({ :action=>'atom' }, :alert => "Something serious happened")
Example of conditions using
f.e.
validates :number, :presence => { :if => :quota_file? } def self.quota_file? quota_file? end
won't refresh updated_at
This will not cause :updated_at column to refresh, while ActiveRecord::Base#increment! would.
looking to bypass validations, callbacks and updated_at?
Take a look at updated_column
http://apidock.com/rails/ActiveRecord/Persistence/update_column
@ssoroka and @drova and future readers
I guess these two have already found a solution, but future readers might have not. index and references do not map perfectly
change_table :foo do |t| t.references :bar t.index :bar_id end
references gets the model name while index gets the column name.
Not working in create_table
When using the index method within a create_table statement, it does not have any side effect - at least not in MySQL.
create_table :comment do |t| t.belongs_to :post t.timestamps # not working inside create_table ! t.index :post_id end
It is working properly in change_table though
change_table :comment do |t| t.belongs_to :user # this works inside change_table t.index :user_id end
Unfortunately this flaw is not reported in any way. The index is just not created.
I have only tested this with the mysql2 driver in Rails 2.3.x. I’m not sure, if this happens in other versions/adapters as well.
:defaults no longer work
I’m afraid that :defaults option doesn’t work anymore.
<%= javascript_include_tag :defaults %>
it loads “defaults.js”
Instead, to load all .js files now use
<%= javascript_include_tag "application" %>
:only, :except and passing in multiple parameters
To specify that the filter should be applied to or excluded from given controller actions, use the :only and :except parameters. To pass in multiple controller actions use an array:
after_filter :authorize, :except => [:index, :show] after_filter :authorize, :only => :delete
Stolen from: http://apidock.com/rails/ActionController/Filters/ClassMethods/before_filter