Recent notes
RSS feedAccepted parameters for validate
Validate method also accepts :on and :if parameters. The default value for :on is :save, the other accepted values are :create and :update
class Comment include ActiveModel::Validations validate :must_be_friends, :on => :create, :if => Proc.new {|comment| some_condition} def must_be_friends errors.add(:base, "Must be friends to leave a comment") unless commenter.friend_of?(commentee) end end
similar to clone
See the clone documentation. I see that ActiveRecord is moving from “clone” (3.0.9) to “dup” (?).
Beware nested with_options clobbers!
Careful:
with_options :foo => :bar do |something| something.with_options :foo => :baz do |inner| what_is(:foo) end end
:foo will be :baz. It will not be [:bar, :baz], for example.
This bit me when trying to do nested with_options for validation where both had :if => something.
If you try to use :id as a non-primary-key field
If you’re using this so that you can repurpose :id for another use, it gets hairy: your ActiveRecord::Base subclass will still use :id to refer to your primary key, whatever it be named.
So when you call [my obj].id = 33, 33 is set as the value of your primary key, not your :id attribute!
Starts with capital letter alternative
Just adding an anchor to the regular expression seems simpler (and was faster in my benchmarks, not that that matters much):
'Abracadabra' =~ /^[A-Z]/
STI - Making callbacks trigger in inherited classes
Assuming we have
class ParentClass < ActiveRecord::Base attr_accessible :type end class ChildClass < ParentClass after_save :perform_something end
Executing
ParentClass.create({:type => "ChildClass"})
will not trigger ChildClass callbacks. What is more, it will return instance of ParentClass instead of ChildClass.
To resolve this issue, you need to define following module
module ActiveRecord module CallbacksAwareSti extend ActiveSupport::Concern module ClassMethods def new(*args, &block) return super(*args, &block) unless args.first.respond_to?(:with_indifferent_access) type = args.first.with_indifferent_access[:type] if type.blank? or (type = type.constantize) == self super(*args, &block) else super(*args, &block).becomes(type) end end end end end
and include it in parent class
class ParentClass < ActiveRecord::Base include ActiveRecord::CallbacksAwareSti attr_accessible :type end
Inspired by http://stackoverflow.com/questions/4518935/activerecord-problems-using-callbacks-and-sti
Undefined Method `mktmpdir' for Dir:Class
Be sure to
require 'tmpdir'
before using it. Read more at http://mikbe.tk/2011/03/07/temporary-directory.
block only and except
Code
class Journal < ActionController::Base # Require authentication for edit and delete. before_filter :authorize, :only => [:edit, :delete] # Passing options to a filter with a block. around_filter(:except => :index) do |controller, action_block| results = Profiler.run(&action_block) controller.response.sub! "</body>", "#{results}</body>" end private def authorize # Redirect to login unless authenticated. end end
Hidden Field Example
Here’s a pseudo code example of a hidden field within an ERB template. A post has many comments and this comment form is in a post’s show view. This would set a comment’s post_id attribute.
<%= form_for(@comment) do |f| %>
<%= f.hidden_field :post_id, :value => @post.id %>
<% end %>
Starts with a Capital Letter
(or any regular expression you’d like)
'Abracadabra'[0..0] =~ /[A-Z]/ # => true
method to use instead
This may be obvious, but the replacement for this method is csrf_meta_tags.
Example from Code School
module Tweets
class ShowPresenter extend ActiveSupport::Memoizable def initialize(tweet) @tweet = tweet end def username @tweet.user.username end def status @tweet.status end def favorites_count @tweet.favorites.count end memoize :username, :status, :favorites_count end end
HTML5 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
BasicObject.new
Instantiates a new blank object (devoid of methods). The only class method of class BasicObject. see “ri BasicObject”
eg,
> o=BasicObject.new (Object doesn’t support #inspect)
>
> o.methods NoMethodError: undefined method `methods’ for #<BasicObject:0x0000000267a0a0>
> def o.to_s > self > end
> nil
> o
> #<BasicObject:0x0000000267a0a0>
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