Recent notes
RSS feedtypo
ActionController::Steaming => ActionController::Streaming
Moved to ActionDispatch::Routing::PolymorphicRoutes
In Rails 3, this has moved to ActionDispatch::Routing::PolymorphicRoutes.
Checks if attribute is equal to '1' by default
It’s easy to overlook the :accept option which dictates that the attribute shall be ‘1’, not ‘yes’, not true, but ‘1’ only for validation to pass.
For ‘1’ shall the value be, no more, no less. ‘1’ shall be the value thou shalt validate, and thy validation shall check for ‘1’. ‘2’ shalt not thou validate, neither ‘3’, nor ‘0’, excepting that thou shall then set the value to ‘1’. true is right out. Once the value ‘1’, being the value of the attribute named, then thou shall have validation and thy object shall be valid.
link to nothing if link_to_if condition is false
When the link_to_if condition is false you can get this helper to display nothing by doing something like this
<%= link_to_if(message.user, 'Poster', message.user){} %>
^ That will display nothing if message.user does not exist.
Includes the dot
Returns the extension including the ‘.’.
E.g.
Pathname("/path/to/file.rb").extname #=> ".rb"
word_wrap with breaking long words
Code
def breaking_word_wrap(text, *args) options = args.extract_options! unless args.blank? options[:line_width] = args[0] || 80 end options.reverse_merge!(:line_width => 80) text = text.split(" ").collect do |word| word.length > options[:line_width] ? word.gsub(/(.{1,#{options[:line_width]}})/, "\\1 ") : word end * " " text.split("\n").collect do |line| line.length > options[:line_width] ? line.gsub(/(.{1,#{options[:line_width]}})(\s+|$)/, "\\1\n").strip : line end * "\n" end breaking_word_wrap("Once upon a supercalifragilisticexpialidocious time",15) # => Once upon a\nsupercalifragil\nisticexpialidoc\nious time
Documentation (v3.0.1)
Documentation for this module (taken from ActiveSupport 3.0.1):
# A typical module looks like this # # module M # def self.included(base) # base.send(:extend, ClassMethods) # base.send(:include, InstanceMethods) # scope :foo, :conditions => { :created_at => nil } # end # # module ClassMethods # def cm; puts 'I am a class method'; end # end # # module InstanceMethods # def im; puts 'I am an instance method'; end # end # end # # By using <tt>ActiveSupport::Concern</tt> the above module could instead be written as: # # module M # extend ActiveSupport::Concern # # included do # scope :foo, :conditions => { :created_at => nil } # end # # module ClassMethods # def cm; puts 'I am a class method'; end # end # # module InstanceMethods # def im; puts 'I am an instance method'; end # end # end
In Rails 3 you can find it here
In Rails 3 - this validation is moved to the HelperMethods
nested attribute gotcha
Just adding to what @diabolist said :
class House
has_many :doors accepts_nested_attributes_for :doors attr_accesible :address, :doors_attributes # NOTE its plural
end
How to perform :onchange ajax call using jQuery (Rails 3)
As remote_function no longer exists in Rails 3, here is some handy substitution
<%= select_tag :assignee_id, options_for_select([["A",1],["B",2]]), :onchange => "$.post('#{model_singular_path(id)}', {'_method':'put', 'model_name[model_field]':this.value} );" %>
You can obviously pass more attributes, change method etc.
NOT Equivalent to Array#reject!
@tadman is wrong. There is a difference and, trust me, it can bite:
1.9.2 > [1,2,3,4].delete_if {|x| x > 10} => [1, 2, 3, 4] 1.9.2 > [1,2,3,4].reject! {|x| x > 10} => nil
That is, if reject! hasn’t rejected anything, it returns nil.
Will raise error on broken symlink
This method will raise Errno::ENOENT on a broken symlink. You should probably rescue it every time you call this method.
correction
I think what metavida meant was
User.find(1, 3) # ActiveRecord::RecordNotFound error
not
User.find_by_id(1, 3) # this will just return user 1
RecordNotFound when any id not found
As an example of bansalakhil’s explanation.
User.find_by_id(1) #=> #<User:0x3d54a3c @attributes={"id"=>1}> User.find_by_id(2) #=> #<User:0x3d519a4 @attributes={"id"=>2}> User.find_by_id(3) #=> nil User.find_by_id(1, 2) #=> an Array with 2 User instances User.find_by_id(1, 3) #=> an ActiveRecord::RecordNotFound error
Get the primary schema's name
If you’re using PostgreSQL and you’ve changed schema, sometimes you need to know what schema you’re in.
ActiveRecord::Base.connection.schema_search_path.split(",").first
A named_scope also responds to model class methods
for instance
class Student < ActiveRecord::Base
named_scope :sophomore, :conditions => 'year=2' def self.eligible_to_vote select{|s| s.age >= 18} end end ss = Student.sophomore.eligible_to_vote
map_with_index
Of course such a method does not exist, however we can simulate it easily
%w(a b c).to_enum(:each_with_index).map{|a,i| "#{a}, #{i}"} => ["a, 0", "b, 1", "c, 2"]
Pluralize Without Count (inline version)
= pluralize(item.categories.count, ‘Category’).sub(/d+s/, ”)
Polymorphic has_many within inherited class gotcha
Given I have following classes
class User < ActiveRecord::Base end class ::User::Agent < ::User has_many :leads, :as => :creator end
I would expect, that running
User::Agent.first.leads
will result in following query
SELECT "leads".* FROM "leads" WHERE ("leads".creator_id = 6 AND "leads".creator_type = 'User::Agent')
however it results in
SELECT "leads".* FROM "leads" WHERE ("leads".creator_id = 6 AND "leads".creator_type = 'User')
Possible solutions:
-
Make User class use STI - polymorphic relations will then retrieve correct class from :type field (however in my situation it was not an option)
-
If You do never instantiate User class itself, mark it as abstract
class User < ActiveRecord::Base self.abstract_class = true end
-
If You do instantiate User class, as last resort You can overwrite base_class for User::Agent
class ::User::Agent < ::User has_many :leads, :as => :creator def self.base_class self end end
-
If none of above is an option and You do not care that You will lose some of relation’s features, You can always
class User::Agent < ::User has_many :leads, :as => :creator, :finder_sql => %q(SELECT "leads".* FROM "leads" WHERE ("leads".creator_id = #{id} AND "leads".creator_type = 'User::Agent')) end
Use super to override, and not alias_method_chain
Somehow, If you want to extend the behaviour of attributes=,
alias_method_chain does not work. It simply breaks (could not find out how exactly).
def attributes_with_some_feature=(new_attributes, guard_protected_attributes = true) attributes_without_some_feature=(new_attributes, guard_protected_attributes) end alias_method_chain :attributes=, :some_feature
this breaks the code. dynamic finders and assignments didn’t work as before (Even though no behaviour has changed yet).
Instead,
def attributes=(new_attributes, guard_protected_attributes = true) # custom code super(new_attributes, guard_protected_attributes) end
does work as expected.
I prefer using alias_method_chain for breaking open existing functionality, but in this case it won’t work.
null to no effects
change_column will not query to replace the null values when you change null to false, even if you have a default set. This may cause the query to fail (may depend on the database used).
change_column_null will optionally take a value to replace nulls if you are setting null to false. If you want to set a default and disallow nulls you likely can’t do both in one change_column call.
doesn't work directly off a class.
for some reason this method only works on relation objects, not directly on an AR class.
# doesn't work User.offset(3).limit(1) # does work User.limit(1).offset(3)
there’s an closed ticket for this here http://rails.lighthouseapp.com/projects/8994/tickets/5688-modeloffsetxlimitx-unknown-offset-method-exception and should be resolved in the next release of rails.
still broken
add_index is a different method. I think this is just a bug and it’s broken.
Validate number
option like :greater_than still supported
use like this
Code example
validates :position, :presence => true, :numericality => {:greater_than => 0}
use raw() instead
Don’t use this method unless you’re sure your string isn’t nil. Instead use the raw() method, which wont raise an exception on nil.
Looking for the docs?
Check the ClassMethods – the docs on filters are there.
needs to be paired with respond_to
Needs to be paired with respond_to at the top of your class.
class MyController < ApplicationController respond_to :js, :html
Sending array parameters
Another technique to use when you need to send an array parameter is pass in the :multiple option.
check_box("puppy", "commands", {:multiple => true}, "sit", nil) check_box("puppy", "commands", {:multiple => true}, "fetch", nil) check_box("puppy", "commands", {:multiple => true}, "roll_over", nil)
If all checkboxes are checked, the paramters will be:
"puppy" => {"commands" => ["sit", "fetch", "roll_over"]}
NOTE: because of the gotcha, the hidden fields will be inserted and any unchecked boxes will be sent as “” (empty string). You will need to filter those values out in your model:
class Dog < ActiveRecord::Base def commands=(commands) commands.reject(&:blank?) end end
Replacement
Use sanitize or connection.quote instead.