Flowdock

Notes posted to Ruby on Rails

RSS feed
September 30, 2011 - (>= v3.0.0)
1 thank

Using a block with image_tag

HTML5 officially supports block-level elements in the anchor tag and Rails 3 allows you to pass a block to image_tag:

<%= image_tag(some_path) do %>

<%= content_tag(:p, "Your link text here")

<% end %>

September 30, 2011 - (v3.0.0 - v3.1.0)
0 thanks

Without module

If you want to have only the path prefix without namespacing your controller, pass :module => false.

Normal:

namespace :account do
  resources :transactions, :only => [:index]
end

account_transactions GET /account/transactions(.:format)
{:controller=>"account/transactions", :action=>"index"}

With :module => false:

namespace :account, :module => false do
  resources :transactions, :only => [:index]
end

account_transactions GET /account/transactions(.:format)
{:controller=>"transactions", :action=>"index"}
September 29, 2011 - (v2.0.0 - v3.1.0)
2 thanks

Additional Format meaning

%e - Day of the month, without leading zero (1..31)

September 27, 2011 - (>= v3.1.0)
0 thanks

1.9 behavior

“In Ruby 1.9 and newer mb_chars returns self’”

This would seem to be a lie. At least in rails 3.1.0 and ruby 1.9.2, mb_chars still returns a proxy object with additional useful methods defined on it that aren’t on a 1.9.2 String.

ruby-1.9.2-p180 :007 >  "àáâãäå".normalize(:kd)
NoMethodError: undefined method `normalize' for "àáâãäå":String

ruby-1.9.2-p180 :008 > "àáâãäå".mb_chars.normalize(:kd)
 => àáâãäå
September 25, 2011
1 thank

Parsing the Date Params into a New Date Object.

Useful for when you need to create a Date object from these manually, such as for reporting.


If the date select input is start_date and it belongs to the report form object:

@start_date = Date.civil(params[:report]["start_date(1i)"].to_i,
                         params[:report]["start_date(2i)"].to_i,
                         params[:report]["start_date(3i)"].to_i)

@start_date.class
# => Date

@start_date
# => Sun, 25 Sep 2011  # For example.

Use a similar method for DateTime situations.

September 17, 2011
0 thanks

this works, but doesn't make sense

does it?

replace(klass.find(ids).index_by { |r| r.id }.values_at(*ids))

equals

replace(klass.find(ids))

I see no point in making it that complicated

September 15, 2011
1 thank

beware of trying to dup in subclass inside class context

The example of adding to an array without effecting superclass:

# Use setters to not propagate changes:
Base.setting = []
Subclass.setting += [:foo]

That’s right as far as it goes. But beware when you are in context of class definition:

class Subclass < Base
   # possibly wrong, ruby seems to get 
   # confused and think you mean a local 
   # var, not the class ivar
   setting += [:foo]

   # But this will work:
   self.setting += [:foo]

   # Or:
   self.setting = self.setting.dup
   self.setting << :foo

   [...]
end
September 14, 2011
0 thanks

Find a Selected Option in a Drop Down.

You can find the selected option (or options for multiple select inputs) with the following:

assert_select('select#membership_year option[selected]').first['value']
September 14, 2011
2 thanks

More on add_to_base

Actually, use

model_instance.errors.add :base, :invalid

to have I18n working.

September 13, 2011
0 thanks

more options

useful options are:

:root => ‘object’, :skip_instruct => true, :indent => 2

:builder can also be used to pass your own Builder::XmlMarkup instance.

September 13, 2011
1 thank

Some unexpected behaviour

When using Array as default value, it behaves more like cattr_accessor…

class A
 attr_accessor_with_default :b, []
end

x = A.new
x.b << 1

#puts x.b.inspect => [1]

y = A.new
y.b << 2

#puts y.b.inspect => [1, 2]
September 9, 2011 - (v3.0.9)
0 thanks

Example usage...

`

Time.now.advance(:days => +2, :hours => +8)

`

September 8, 2011 - (>= v3.0.9)
0 thanks

First example simplified

The first code example may be simplified, since the call to method to_xml is made implicitly anyway:

def index
  @people = Person.find :all

  respond_to do |format|
    format.html
    format.xml { render :xml => @people }
  end
end
September 7, 2011 - (v3.0.0 - v3.0.9)
0 thanks

Tested w/ Rails 3 and returning true/false ignored

Per http://ar.rubyonrails.org/classes/ActiveRecord/Callbacks.html “If a before_* callback returns false, all the later callbacks and the associated action are cancelled. If an after_* callback returns false, all the later callbacks are cancelled.” [and presumably associated action is not canceled]

So, the callback chain will be broken, but the save will still happen.

Also ran into this: http://innergytech.wordpress.com/2010/03/08/dont-put-validations-in-after_save/

September 7, 2011 - (>= v3.0.9)
0 thanks

Passing an object as argument

It is possible to pass an instance of a record to the method. See the documentation of polymorphic_url (http://apidock.com/rails/ActionDispatch/Routing/PolymorphicRoutes).

September 5, 2011
0 thanks

(Another) Pluralize Without Showing the Count

Thought it would be best to take the source code from pluralize and just remove the count from the output.

Create this helper method in application_helper.rb

# Pluralize without showing the count.
def simple_pluralize count, singular, plural=nil
  ((count == 1 || count =~ /^1(\.0+)?$/) ? singular : (plural || singular.pluralize))
end

This allows you to pass in in the plural word to use as well.

August 30, 2011 - (>= v3.0.0)
1 thank

Does not work for has_one associations

If you are using this to validate that a has_one association has been made with another object this will not work, as the test used in the AssociatedValidator #validates_each method tests for nil and then ignores this object.

To test for association with a has_one association you can use the following code:

validate do
  [:teacher, :book].each do |attr|
    errors.add(attr, "is required") if self.send(attr).nil?
  end
end
August 23, 2011
0 thanks

the correct return value of html_escape in example above

the correct return is:

# => is a &gt; 0 &amp; a &lt; 10?

August 15, 2011
1 thank

The :path option

The path option will actually set the path and not the prefix I have found in Rails 3.0.5.

Example

resources :my_reports, :path => 'my-reports'

All actions for this resource will now be at /my-reports.

August 14, 2011
0 thanks

Security issue

One thing to note about the code above is that it could have a security issue. If the user changes his/her password, the authentication token should expire. Hence, in a production scenario you should put in the password salt or something to allow the token to become invalidated.

August 11, 2011
2 thanks

More AREL compliant style is also possible

Code example

Person.where(:name => 'David').exists?
August 11, 2011 - (>= v3.0.0)
0 thanks

Look at mail gem

If you’re looking for mailer methods like “deliver” for rails 3 or later, you should look into “mail” gem: http://github.com/mikel/mail

August 9, 2011
1 thank

HTML5 support

To support multiple file selection simply pass :multiple => true in the options hash:

file_field_tag 'file', :accept => 'image/jpeg', :multiple => true
August 5, 2011
0 thanks

Speccing read_only requirements

To test if an attribute is defined readonly:

class MyModel < ActiveRecord::Base
  attr_readonly :important_type_thingie
end

#RSpec
describe MyModel do
 its('class.readonly_attributes') { should include "important_type_thingie" }

 it "should not update the thingie" do
   m = create :my_model, :important_type_thingie => 'foo'
   m.update_attributes :important_type_thingie => 'bar'
   m.reload.important_type_thingie.should eql 'foo'
 end
end
August 4, 2011
1 thank

Examples out of order

The second and third examples should exchange places to fit with their explanations.

July 31, 2011 - (>= v3.0.9)
1 thank

Rescuing DeleteRestrictionError via flash message

Model

class ShareType < ActiveRecord::Base
  has_many :shares, :dependent => :restrict
end

Controller

class ShareTypesController < ApplicationController
  def destroy
    begin
      @share_type.destroy
      flash[:success] = "successfully destroyed." 
    rescue ActiveRecord::DeleteRestrictionError => e
      @share_type.errors.add(:base, e)
      flash[:error] = "#{e}"
    ensure
      redirect_to share_types_url
    end
  end
end
July 29, 2011 - (v2.1.0)
0 thanks

default value for :use_full_path

FYI, It in Rails 2.1.1 the default value for :use_full_path has changed from true to false.

This will show up as an error stating “No such file or directory”

July 29, 2011
0 thanks

Basic usage

Basic usage example:

class User < ActiveRecord::Base
   #...
   skip_callback :create, :after, :send_welcome_email
   #...
end
July 28, 2011 - (v3.0.0 - v3.0.9)
0 thanks

sure, but what types are there to chose from?

the ‘symbol’ parameter is not something specific like ‘:after_save’, but rather ‘:save’

I suppose ‘:update’ works as well.