Notes posted to Ruby on Rails
RSS feedSmall notice about recognize urls with specific HTTP verbs
This is wrong ruby syntax:
assert_recognizes {:controller => 'items', :action => 'create'}, {:path => 'items', :method => :post}
Parentheses are obligatory in this case:
assert_recognizes({:controller => 'items', :action => 'create'}, {:path => 'items', :method => :post})
To find element ant not to find element
If you want to see administration panel:
assert_select "div.admin-panel"
But if you want to NOT see administration panel just write:
assert_no_tag 'div', :attributes => {:class => 'admin-panel'}
With multiple parameters
Example
remote_function( :url => some_remote_function_path, :with => "'key1='+$('elem_id').value +'&key2='+$('elem_id').value+ '&this_elem_value='+value" )
with_exclusive_scope example by Ramon broken in latest Rails
The example Ramon gave works within the model itself, i.e.
class Article def closed with_exclusive_scope { find(:all) } end end
However, from what I can see, this approach does not work within a controller. You may be wanting to use
Article.with_exclusive_scope { find(:all) } #=> "SELECT * FROM 'articles'
But it will error out about find(:all) not existing on ArticlesController. To get around this, you must now do
Article.with_exclusive_scope { Article.find(:all) } #=> "SELECT * FROM 'articles'
In otherwards, find(:all) isn’t being executed in the scope of the model, but in the controller in which its called.
Took me a minute or two to find out, so I thought I’d let others know.
Current Database Name: Sqlite version
Get the current database name when using Sqlite:
ActiveRecord::Base.connection.instance_variable_get(:@config)[:database].split('/').last
Content type for emails with attachments
Be aware that if you want to send emails with attachments, you probably want to use the content type multipart/mixed for the overall email.
The MIME time multipart/alternative is intended for emails where each part is a different representation of the same message.
After following the 2.3.2 documentation we used multipart/alternative to attach files to our mails, however this then caused Hotmail to ignore the attachments. It turns out it thought they were all alternative versions of the HTML content (which it could already display, so the alternatives weren’t necessary)
Re: Validate an optional URL field
Actually it’s easier to use validates_format_of for this task. Please refer to the comments under the doc.
Join multiple tables
It’s easy to join multiple tables too. In this case we have:
class Article belongs_to :feed end class Feed has_many :articles belongs_to :source end class Source has_many :feeds # t.bool :visible end
You can search articles and specify a condition on the sources table.
Article.find(:all, :conditions => { :feeds => { :sources => { :visible => true }}}, :joins => [:feed => :source],
Built-in cache stores
Built-in cache stores are:
-
:file_store (ActiveSupport::Cache::FileStore)
-
:memory_store (ActiveSupport::Cache::MemoryStore)
-
:drb_store (ActiveSupport::Cache::DRbStore)
-
:mem_cache_store (ActiveSupport::Cache::MemCacheStore)
-
:compressed_mem_cache_store (ActiveSupport::Cache::CompressedMemCacheStore)
Most common use case
Most common use case is probably:
Rails.cache.fetch "some key" do compute some value end
This computes some value and caches it. Subsequent invocations will return cached value (as long as it is still cached).
Documentation
This method only returns a cache manager object of sorts, to see what you can do with it, see ActiveSupport::Cache::Store.
Documentation bug
When adding the :target option, the documentation states that you should user :href_options like so:
auto_link(post_body, :href_options => { :target => '_blank' })
However, I could only get it to work using :html instead:
auto_link(post_body, :html => { :target => '_blank' })
I’m using Rails 2.2.2, but I believe that this also happens for more recent version .
*Described above
The documentation is referring to the module documentation: ActionController::Cookies
Binding parameter deprecated in > 2.2
Supplying the binding argument produces a deprecation warning in 2.2 and newer:
DEPRECATION WARNING: The binding argument of #concat is no longer needed. Please remove it from your views and helpers.
Separating date and time
Option :datetime_separator can be set too. Default is ‘ — ’
How to set default value to NULL
To set default value to NULL you can use change_column method instead, for example:
change_column :suppliers, :qualification, :string, :default => nil
Just make sure you don’t change data type accidentally ;-)
can we use both sortable_element and drop_recieving_element on same list
I had a sortable_element that was also a drop_receiving_element. element it’s dropping while dropping element into selected container ,but not element dragging is not viewble to end users. it’s dragging only in sortable list area. but mu droppble contanier is another one.i used scroll => true in sortable_element . but its not working for sorting and dropping element into contianer. could u letme know how to use both methods on same list
Paginating grouped records
If you are grouping similar records and paginating you might need to use :group You’ll want to :select only the field you’re collapsing on probably.
Model.count(:select => :attribute, :group => :attribute)
This will return an OrderedHash of your attributes with a count for each.
{"Column Content" => 6, "Another Column's Content" => 8}
You’ll need a second query to pull all of your records out.
Return True
As is the case with the before_validation and before_save callbacks, returning false will break the callback chain. For example, the expire_cache_id method will not run if Rails.cache.expire returns false (as it will if the key is not cached with memcache).
Returning False Example (Bad)
after_save :expire_cache_by_name after_save :expire_cache_by_id def expire_cache_by_name Rails.cache.expire("my_object:name:#{self.name}") end def expire_cache_by_id Rails.cache.expire("my_object:#{self.id}") end
Returning True Example (Good)
def expire_cache_by_name Rails.cache.expire("my_object:name:#{self.name}") return true end def expire_cache_by_id Rails.cache.expire("my_object:#{self.id}") return true end
Overriding default validation messages
Before Rails 2.2 you could globally customize the default validation error messages by changing AR::Base.default_error_messages. The messages have now been moved to i18n, so to customize them in 2.2 and up, just create a locales/ folder in your config/ folder, copy activerecord/lib/active_record/locale/en.yml (in Rails source) to config/locales/en.yml, and then change the strings inside. As szeryf indicated below, the strings of interest are activerecord.errors.messages.
Instance method
Please note that this is an instance method, not a class method (which seemed more logical for me and took me a while to see what’s wrong). So, you call it like this:
User.new.from_json '{"id": 1, "name": "DHH"}' # RIGHT!
not like this:
User.from_json '{"id": 1, "name": "DHH"}' # WRONG!
Format meaning:
%a - The abbreviated weekday name (“Sun”)
%A - The full weekday name (“Sunday”)
%b - The abbreviated month name (“Jan”)
%B - The full month name (“January”)
%c - The preferred local date and time representation
%d - Day of the month (01..31)
%H - Hour of the day, 24-hour clock (00..23)
%I - Hour of the day, 12-hour clock (01..12)
%j - Day of the year (001..366)
%m - Month of the year (01..12)
%M - Minute of the hour (00..59)
%p - Meridian indicator (“AM” or “PM”)
%S - Second of the minute (00..60)
%U - Week number of the current year, starting with the first Sunday as the first day of the first week (00..53)
%W - Week number of the current year, starting with the first Monday as the firstday of the first week (00..53)
%w - Day of the week (Sunday is 0, 0..6)
%x - Preferred representation for the date alone, no time
%X - Preferred representation for the time alone, no date
%y - Year without a century (00..99)
%Y - Year with century
%Z - Time zone name
%% - Literal “%” character
Format meaning
%a - The abbreviated weekday name (“Sun”)
%A - The full weekday name (“Sunday”)
%b - The abbreviated month name (“Jan”)
%B - The full month name (“January”)
%c - The preferred local date and time representation
%d - Day of the month (01..31)
%H - Hour of the day, 24-hour clock (00..23)
%I - Hour of the day, 12-hour clock (01..12)
%j - Day of the year (001..366)
%m - Month of the year (01..12)
%M - Minute of the hour (00..59)
%p - Meridian indicator (“AM” or “PM”)
%S - Second of the minute (00..60)
%U - Week number of the current year, starting with the first Sunday as the first day of the first week (00..53)
%W - Week number of the current year, starting with the first Monday as the firstday of the first week (00..53)
%w - Day of the week (Sunday is 0, 0..6)
%x - Preferred representation for the date alone, no time
%X - Preferred representation for the time alone, no date
%y - Year without a century (00..99)
%Y - Year with century
%% - Literal “%” character
Sanitize in controllers, models, or libs -- *with* options
A Follow-up to k776’s note. If you want to specify tags or attributes, you should change your initializer to:
class String def sanitize(options={}) ActionController::Base.helpers.sanitize(self, options) end end
Then you can call it from any string like so:
'string'.sanitize(:tags => %w(table td tr), :attributes => %w(style id))
Also works with other markup
such as XML, not only HTML as suggested in the text.
Time.now in views.
Be careful if you use Time.now in views with time zone support enabled, as this will not actually do the time zone conversion.
Instead, use Time.zone.now.
Change Column. pt-br
Em sua migration escreva da seguinte forma:
Exemplo de uso.
def self.up change_column :sua_tabela, :seu_campo, :seu_tipo_campo end
Change Column.
Into your migration write the follow:
Using Exemple
def self.up change_column :yourtable, :your_field, :your_type_field end
Options
Available options are (none of these exists by default):
* :limit - Requests a maximum column length. This is number of characters for :string and :text columns and number of bytes for :binary and :integer columns. * :default - The column‘s default value. Use nil for NULL. * :null - Allows or disallows NULL values in the column. This option could have been named :null_allowed. * :precision - Specifies the precision for a :decimal column. * :scale - Specifies the scale for a :decimal column.
Pretty Printing Routes
if you’d like to check out your routes in the console, you can do something like:
routes = ActionController::Routing::Routes
# which will return a RouteSet puts routes.routes
which’ll give you a nice output like: GET /messages/ {:action=>“index”, :controller=>“messages”} GET /messages.:format/ {:action=>“index”, :controller=>“messages”} POST /messages/ {:action=>“create”, :controller=>“messages”} POST /messages.:format/ {:action=>“create”, :controller=>“messages”} GET /messages/new/ {:action=>“new”, :controller=>“messages”} GET /messages/new.:format/ {:action=>“new”, :controller=>“messages”} GET /messages/:id/edit/ {:action=>“edit”, :controller=>“messages”} GET /messages/:id/edit.:format/ {:action=>“edit”, :controller=>“messages”} GET /messages/:id/ {:action=>“show”, :controller=>“messages”} GET /messages/:id.:format/ {:action=>“show”, :controller=>“messages”} PUT /messages/:id/ {:action=>“update”, :controller=>“messages”} PUT /messages/:id.:format/ {:action=>“update”, :controller=>“messages”} DELETE /messages/:id/ {:action=>“destroy”, :controller=>“messages”} DELETE /messages/:id.:format/ {:action=>“destroy”, :controller=>“messages”}