Recent notes
RSS feedUseful for mocking out IO methods like #gets and #puts
This class is helpful when testing certain classes of software libraries that are dependent on console input and output, similar to some testing uses of Java’s StringBuffer
output is buffered and will not appear until flush
Output is buffered on most operating systems. To override this behavior, force the stdout or other io to sync
STDOUT.sync = true
Use ModelClass.model_name.human
eg. Person.model_name.human will return the i18n name for the model.
see for more info: ActiveModel::Translation
Preserve order of elements within fields_for
I had the @colleagues collection prepared that I wanted to be rendered within fields_for block. However it was searchlogic object with filtering/sorting applied, and the sort order was not preserved in resultant view.
<%= f.fields_for :evaluators, @colleagues do |builder| %> <%= render "colleague", :f => builder %> <% end %>
Solution to this problem was typecasting this collection to array
<%= f.fields_for :evaluators, @colleagues.to_a do |builder| %> <%= render "colleague", :f => builder %> <% end %>
Custom validator with i18n support
Here is modified EmailValidator from the example above:
class EmailValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) record.errors.add(attribute, options[:message] || :email) unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i end end
And locale:
en: activerecord: errors: messages: email: "is not an email"
Bind the named method to the receiver
Binds the named method to the receiver, returning a Method object with access to the internals of the receiver, such as self and instance variables.
Anchor option
It’s not documented, but :anchor is an option.
polymorphic_path(commentable, :anchor => 'comments')
will return:
/article/1#comments
Mistake in example for Rails 3
This code doesn’t work:
activemodel: attribute: post: cost: "Total cost"
Everything is OK with this one:
activerecord: attributes: post: cost: "Total cost"
Nice german translation independet of structure of a sentence
Eine pragmatische Lösung für das Übersetzungsproblem der Rails Methode distance_of_time_in_words(). Im Deutschen wird je nach Satzbau eine andere Ausgabe benötigt.
Vor mehr als 5 Monaten“/”Vor etwa einem Jahr“ — statt wie im Original ”Dauer: mehr als 5 Monate“/”Dauer: etwa 1 Jahr
About the options argument
The options are not documented, but of course you can use the same options than submit_tag.
Note that all non-documented options are simply passed to the input tag. Amongst other things, this allows you to change the default name attribute (commit):
form.submit 'Cancel', :name => 'cancel'
That’s very handy in forms with multiple submit buttons, this way the controller can easily check in the params which action was submitted.
using joins, group, having
Code example
named_scope :red, :joins => [:color_lis => :color], :group => "color.id", :having => ["color.xx IS NULL"]
No Layout (fixed typo)
@wiseleyb: Seems to be a typo, should be:
render_to_string(:action => "users/profile", :layout => false)
Documentation of I18N
lives f.ex. here: http://rdoc.info/github/svenfuchs/i18n/master/I18n
Re: Doesn't work? Don't think it ever has.
Instead of
create_table :user_follows, :force => true do |t| t.references :user t.references :followed_user t.timestamps t.index :user t.index :followed_user end
Try
create_table :user_follows, :force => true do |t| t.references :user t.references :followed_user t.timestamps end index :user_follows , :user index :user_follows , :followed_user
It looks like the provided examples are incorrect…
No concurrency
If you want to handle concurrency, this doesn’t work:
a = Article.first b = Article.first a.increment!(:view_count) b.increment!(:view_count) a.reload.view_count # -> 1 b.reload.view_count # -> 1
Instead, use SQL:
def increment_with_sql!(attribute, by = 1) raise ArgumentError("Invalid attribute: #{attribute}") unless attribute_names.include?(attribute.to_s) original_value_sql = "CASE WHEN `#{attribute}` IS NULL THEN 0 ELSE `#{attribute}` END" self.class.update_all("`#{attribute}` = #{original_value_sql} + #{by.to_i}", "id = #{id}") reload end
bad idea.
Just a note, ypetya’s idea of using a before filter to set the primary key wont scale. transactions will eventually step on each other and probably end up with duplicate key ids, unless you have some other method to ensure uniqueness.
You’d be better off using mysql to generate the default integer primary key and have a secondary string “key” field.
Doesn't work? Don't think it ever has.
This doesn’t work for me. I do something like:
create_table :user_follows, :force => true do |t| t.references :user t.references :followed_user t.timestamps t.index :user t.index :followed_user end
and I get:
rake aborted! An error has occurred, all later migrations canceled: undefined method `index' for #<ActiveRecord::ConnectionAdapters::TableDefinition:0x106c02220>
add_index has the same effect.
takes ActiveRecord object as an arg as well
One undocumented feature, you can do this:
person = Person.first Person.exists?(person) # => returns true
This came in handy for me when I needed to see if something belonged to a particular scope.
scope = "created_rails" person = Person.find_by_name "dhh" Person.send(scope).exists?(person) # => returns true
Obviously this relies on you having a named_scope in your Person model called “created_rails”.
Don't forget about as
:as is a good but poorly document argument to rendering a collection:
<%= render :partial => 'some_partial', :collection => an_array, :as => :better_name -%>
Which will give you each element of an_array in the partial in a local variable named better_name not some_partial.
Set hour and/or minutes
To set the hour and/or the minutes, you can use:
<%= f.datetime_select(:offer_end, :default => { :hour => 23, :minute => 59 }) %>
Undocumented :inverse_of option
Support for the :inverse_of option was backported to 2.3.6+.
Here’s the description from the original commit: http://github.com/rails/rails/commit/ccea98389abbf150b886c9f964b1def47f00f237
You can now add an :inverse_of option to has_one, has_many and belongs_to associations. This is best described with an example:
class Man < ActiveRecord::Base has_one :face, :inverse_of => :man end class Face < ActiveRecord::Base belongs_to :man, :inverse_of => :face end m = Man.first f = m.face
Without :inverse_of m and f.man would be different instances of the same object (f.man being pulled from the database again). With these new :inverse_of options m and f.man are the same in memory instance.
Currently :inverse_of supports has_one and has_many (but not the :through variants) associations. It also supplies inverse support for belongs_to associations where the inverse is a has_one and it’s not a polymorphic.
Undocumented :inverse_of option
Support for the :inverse_of option was backported to 2.3.6+.
Here’s the description from the original commit: http://github.com/rails/rails/commit/ccea98389abbf150b886c9f964b1def47f00f237
You can now add an :inverse_of option to has_one, has_many and belongs_to associations. This is best described with an example:
class Man < ActiveRecord::Base has_one :face, :inverse_of => :man end class Face < ActiveRecord::Base belongs_to :man, :inverse_of => :face end m = Man.first f = m.face
Without :inverse_of m and f.man would be different instances of the same object (f.man being pulled from the database again). With these new :inverse_of options m and f.man are the same in memory instance.
Currently :inverse_of supports has_one and has_many (but not the :through variants) associations. It also supplies inverse support for belongs_to associations where the inverse is a has_one and it’s not a polymorphic.
Undocumented :inverse_of option
Support for the :inverse_of option was backported to 2.3.6+.
Here’s the description from the original commit: http://github.com/rails/rails/commit/ccea98389abbf150b886c9f964b1def47f00f237
You can now add an :inverse_of option to has_one, has_many and belongs_to associations. This is best described with an example:
class Man < ActiveRecord::Base has_one :face, :inverse_of => :man end class Face < ActiveRecord::Base belongs_to :man, :inverse_of => :face end m = Man.first f = m.face
Without :inverse_of m and f.man would be different instances of the same object (f.man being pulled from the database again). With these new :inverse_of options m and f.man are the same in memory instance.
Currently :inverse_of supports has_one and has_many (but not the :through variants) associations. It also supplies inverse support for belongs_to associations where the inverse is a has_one and it’s not a polymorphic.
Validating presence of parent in child
When creating a parent and its children using nested attributes, you can use the :inverse_of option on the association to correctly set the parent back references:
class Parent < ActiveRecord::Base has_many :children, :inverse_of => :parent accepts_nested_attributes_for :children end class Child < ActiveRecord::Base belongs_to :parent validates_presence_of :parent end