Flowdock

Notes posted to Ruby on Rails

RSS feed
July 1, 2011 - (>= v3.0.0)
0 thanks

Common Validator options

Most validators will support all of the following common options: (Through ActiveModel::Errors::CALLBACK_OPTIONS (http://apidock.com/rails/ActiveModel/Errors))

  • :if

  • :unless

  • :allow_blank

  • :allow_nil

July 1, 2011 - (<= v3.0.9)
0 thanks

Another way to use

<%=

link_to_unless_current("Profile", profile_path) 

%> also works (instead of pointing to controller/action)

June 29, 2011
1 thank

Default values

For common attributes in several models, you can set a default human name like this:

de.yml

de:
  attributes:
    bez: Bezeichnung
    abk: Abkürzung
June 29, 2011
0 thanks

Updating nested attributes of one-to-one associations

As the documentation implicitly mentions, when updating nested attributes of a one-to-one relationship, you need to pass the ID of the nested attribute itself, otherwise a new record will be created.

This works fine:

params = { :member => { :avatar_attributes => { :id => '2', :icon => 'sad' } } }

However, the following line will build and save a new record, which is usually not what you want for one-to-one:

params = { :member => { :avatar_attributes => { :icon => 'sad' } } }

Alternatively, you can use the ‘update_only’ option. This option will ensure that an existing record will always be updated, even if the ID is not specified:

accepts_nested_attributes_for :avatar, :update_only => true
June 28, 2011 - (v3.0.9)
0 thanks

available column types

Rails 3.0.9 update for RobinWu’s post

Available column types:

:string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean

Example:

MyClass < ActiveRecord::Migration

def change
  create_table :myclass do |t|
    t.string :name
    t.text :content
end

end

June 28, 2011
0 thanks

Typo in example above

You aren’t mistaken. That is an error in the example with the block above. There’s an extra ‘(’ character.

June 24, 2011 - (v3.0.0 - v3.0.9)
1 thank

RailsCast about Responders

See Ryan Bate’s excellent RailsCast #224 about Responders in Rails 3.x: http://asciicasts.com/episodes/224-controllers-in-rails-3

June 23, 2011
0 thanks

RE: Don't Use to_formatted_s(:db) on an Array of IDs

The reason it doesnt work @joshuapinter for IDs is because if you look at the source:

case format
  when :db
    if respond_to?(:empty?) && self.empty?
      "null"
    else
      collect { |element| element.id }.join(",") # look at this line
    end
  else
    to_default_s
end

It maps/collects the object ids and then joins them using a comma ; so in the case of 60 for instance :

60.object_id #=> 121

60.id #=> 121

June 22, 2011
1 thank

:url conflicts with :format

If you are passing both :url and :format, url overwrites the use of format, so you’ll need to pass it in the url like so:

form_for user, :url => user_path(@user, :format => :json)
June 21, 2011 - (v3.0.0 - v3.0.9)
1 thank

Clear form

for clear a form, use this:

<%= f.submit "clear", :type => "reset" %>
June 20, 2011
0 thanks

Typecasting return values

A better way to typecast the result array is to use AR’s typecasting capabilities. Example:

column = Company.columns_hash['id']
select_values("SELECT id FROM companies LIMIT 3").map do |value|
  column.type_cast(value)
end
June 17, 2011
0 thanks

don't forget :root

You can rename the root tag if you don’t like what is being generated.

line_item.to_xml(:skip_instruct => true, :root => 'line-item')
June 17, 2011 - (>= v3.0.0)
0 thanks

require it

require ‘action_dispatch/testing/test_process’

June 17, 2011
0 thanks

select_values returns Strings for postgreSQL

Will return strings too when using postgreSQL and gem pg (0.11.0).

June 17, 2011
1 thank

bug's fixed, though

in 3.1.0. it works in sqlite3 even, via nested query

but 3.0.3, 3.0.7-9 all broken

June 16, 2011 - (>= v3.0.0)
1 thank

validating a database column acceptance

accept option should be set to true if you are validating a database column, since the attribute is typecast from “1” to true before validation

validates :terms,
  acceptance: {
    allow_nil: false,
    accept: true
  }
June 15, 2011
1 thank

Unusual block calling

It is important to note that the block form of this method is unlike any other block form in Rails. You would expect this to work:

<%= f.label :terms_and_conditions do %>
  Accept <%= link_to_page 'Terms and Conditions' %>
<% end %>

But doing this ends up messing up the form (I ended up with the form repeating itself). Instead you need to do:

<%= f.label :terms_and_conditions do
  'Accept ' + link_to_page('Terms and Conditions')
end %>

Which is really only mildly better than not using the block form:

<%= f.label :terms_and_conditions,
  'Accept ' + link_to_page('Terms and Conditions') %>

You are actually better of using capture if your code lends itself to the first non-working form:

<%= f.label :terms_and_conditions, (capture do %>
  Accept <%= link_to_page 'Terms and Conditions' %>
<% end) %>

Or if you prefer brackets to parenthesis you can do:

<%= f.label :terms_and_conditions, capture { %>
  Accept <%= link_to_page 'Terms and Conditions' %>
<% } %>
June 15, 2011 - (>= v2.0.0)
1 thank
June 15, 2011
1 thank

bug?

beware, update_all silently ignores :limit and :order option in 3.0.8.

I’ve fixed my code temporarily with

update_all "foo=1 where #{myscope.where_values} limit 1"
June 14, 2011 - (>= v2.3.2)
1 thank

Set ids when using a collection of values

The trick to getting the helper to populate a unique HTML ID and for rails to recognise a collection is to give the helper a unique ‘name’ and to set the :name symbol to parameter with an array symbol ‘[]’.

<% Cars.each do |c| %>
  <%= check_box_tag "car_ids[#{c.id}]", c.id, :name => "car_ids[]" %>
<% end %>
June 10, 2011
0 thanks

Typo in matches? example

Iphone example should be def self.matches?(request)

June 4, 2011 - (>= v3.0.0)
4 thanks

finding without default scopes in rails 3

if you want to find without default scopes in rails 3 and with_exclusive_scope is giving you protected method errors in controllers, use unscoped for a similar purpose

June 1, 2011 - (>= v3.0.0)
0 thanks

Catching rollback and re-raise exception

In response to wiseleyb, I don’t believe that you could put “rescue” in a transaction block, let alone catching ActiveRecord::Rollback. It would lead you to an “unexpected kRESCUE” error.

I think this is more appropriate.

def start_transaction
  Company.transaction do
    # don't forget the bang to make sure it raise
    # exception or the transaction won't rollback
    user.save!
    company.save!
    x=1/0

    return true
  end

  # re-raise exception here
  raise "Exception!"
end

Then you could call the method in another place, and it would raise rollback and other exception.

...
  # would return the "Exception!" if rollback occurs
  # it would also still trigger another exception other
  # than rollback.
  start_transaction
...
May 31, 2011 - (>= v3.0.0)
0 thanks

return random element

>> a = [1,2,3] >> a.sample 2

the same as

>> a[rand(a.length - 1)] 1

May 26, 2011
0 thanks

Don't Use to_formatted_s(:db) on an Array of IDs

I thought using to_formatted_s(:db) on an array of ids would separate them with commas in a nice way. Wrong. It does, but it also changes the numbers.

Wrong

[60, 271, 280, 283].to_formatted_s(:db)
# => "121,543,561,567"    # Completely different numbers!

Instead, use the join method:

Right

[60, 271, 280, 283].join(",")
# => "60,271,280,283"      # Much better

I think this has to do with (:db) being used for formatting dates but I’m not sure.

May 24, 2011
2 thanks

must be first

A little gotcha I ran into.

This must be defined before you define your relationships.

ie:

class Ticket < ActiveRecord::Base
  set_table_name 'ticket'
  belongs_to :customer
  has_one :account, :through => :customer
end

if you do the relationships first it will not use the correct table name on the lookups.

May 23, 2011 - (>= v3.0.5)
5 thanks

Change to the way the block is handled

At least in 3.0.5, some of the previous examples no longer work: ActionView seems to quietly ignore Array content.

If you were using code of the form

content_tag(:li, nil, :class => 'someClass') {
  arr.collect { |x|
    content_tag(:ul, x)
  }
}

it now needs to look like

content_tag(:li, nil, :class => 'someClass') {
  arr.reduce('') { |c, x|
    c << content_tag(:ul, x)
  }.html_safe
}
May 20, 2011 - (>= v3.0.0)
0 thanks

relative_url_root= no longer exists in Rails 3.0

Rails 3.0 does this with scope in config/routes.rb

scope "/exampleapp" do
  resources :examples
  root :to => "examples#index"
end
May 6, 2011
0 thanks

Asserting Emails

–setup_mailer.rb in config/initializers –rails g mailer MailerName –methods in mailer_name.rb –files in views/mailer_name –MailerName.method(@object).deliver in object controller

May 6, 2011
0 thanks

Using OpenID

–rails g nifty:authentication –redo rake db:migrate –add: before_filter :login_required, :except => :index to appropriate controllers.