Flowdock

Recent notes

RSS feed
December 7, 2012
0 thanks

Beware: default system crypt functionality silently ignores characters beyond the 8th

On some systems:

"1".crypt('aa')                     => "aacFCuAIHhrCM"
"12".crypt('aa')                    => "aa8dJzr7DFMPA"
"123".crypt('aa')                   => "aamrgyQfDFSHw"
"1234".crypt('aa')                  => "aatxRPdZ/m52."
"12345".crypt('aa')                 => "aajt.4s3e3SZA"
"123456".crypt('aa')                => "aaAN1ZUwjW7to"
"1234567".crypt('aa')               => "aaOK9MRbwVNmQ"
"12345678".crypt('aa')              => "aaNN3X.PL2piw"
"123456789".crypt('aa')             => "aaNN3X.PL2piw"
"1234567890".crypt('aa')            => "aaNN3X.PL2piw"
"1234567890abcdefghij".crypt('aa')  => "aaNN3X.PL2piw"
December 5, 2012 - (v3.2.8)
0 thanks

you will be redirect to signin, when you want to create post before signin

code

def test_should_signin_first_before_add_post
  get "/admin/posts/new"
  follow_redirect!
end
December 5, 2012 - (v3.2.8)
1 thank

post user authentication info to sessions create action

post_via_redirect(“sessions”, {:user=>{:email=> user.email, :password => user.password}})

December 1, 2012
0 thanks

This method is deprecated in rspec 2.0

  • be_close(1, 0.1) is deprecated.

  • please use be_within(0.1).of(1) instead.

November 30, 2012
0 thanks

Beware: virtual attributes are ignored

Even though validations are called, virtual attributes are ignored.

November 30, 2012 - (v3.2.3)
0 thanks

Can't find documention on :find_by option

I found code that had a :find_by option on belongs_to. I’m sure it’s more or less self explanatory, but I couldn’t find it listed anywhere as an option.

My bad, belongs_to was in a controller, not a model.

November 28, 2012 - (>= v3.0.0)
0 thanks

String to date conversion not necessarily symmetric

Note that converting from Date to String and back again is not necessarily symmetric, because the conversion to string may result in a format that is not properly converted by `to_date`.

For one thing, `to_date` sets the century argument in _parse to false. Thus if the default date format has a two-digit year, like the :short one, the century will be dropped.

Date.today.to_s.to_date #=> Mon, 28 Nov 0012 
November 24, 2012 - (>= v3.1.0)
0 thanks

Actually one can see from the source that it just calls utc

From utc:

Returns a Time or DateTime instance that represents the time in UTC.

Seems to have changed in 3.1.0

November 24, 2012 - (v3.0.5 - v3.2.8)
0 thanks

Use collect instead of inject/reduce

You can still use collect when you nest content_tag . Just join the collection in the end and remember to add html_safe if you don’t want your html to be escaped.

a = ['a','b','c']
content_tag(:ul, :class => 'a class') do
  a.collect do |item|
    content_tag(:li, item)
  end.join.html_safe
end
November 16, 2012
0 thanks

The last existing version

It says: The last existing version, and yet when I run a rails console in a 3.0.17 and try the method, it just works. Or does it mean it was never worked on past 2.3.8 ?

November 14, 2012
0 thanks

What artemave said.

I’d remove my original note if I could, but I can’t see a way how.

November 6, 2012
0 thanks

Selected parameter

If you want multiple options to be selected by default you can pass an array of values as “selected” option. It should be obvious, but odradek’s and batarski’s notes can confuse somebody in this case.

November 6, 2012 - (>= v3.0.0)
0 thanks

attributes that have the same names as options

For reasons that are beyond my comprehension, this piece of code

class Working

  include ActiveModel::Validations

  attr_accessor :format

  validates :format, :presence => true, :format => { :with => /\AWorking/ }

end

works (NOTE: it has an attribute that has the same name of an option), while this

class NotWorking < ActiveRecord::Base

  validates :format, :presence => true, :format => { :with => /\ANot Working/ }

end

does not (assuming that you have a legacy db in which you can’t change the names of the columns). It throws an ArgumentError at you. However, a crude hack is to add an explicit accessor to the :format method, like this

class WorkingAgain < ActiveRecord::Base

  validates :format, :presence => true, :format => { :with => /\AWorking again/ }

  def format
    read_attribute(:format)
  end

end

Any explanation is welcome.

November 5, 2012 - (v3.0.0 - v3.2.8)
0 thanks

Specifying an accept header in your tests

To specify an accept header, you need to pass it in the second hash like this:

get '/url', nil, {'HTTP_ACCEPT' => 'application/json'}

The documentation says everything is uppercased and HTTP_ is appended when necessary, but that wasn’t working for me.

October 26, 2012 - (v1.2.0 - v3.2.8)
0 thanks

is now a subclass of Hash that preserves order (or _is_ a Hash if running Ruby 1.9 or greater)

You might not realize it preserves order because it delegates inspect to its super-class, Hash, which doesn’t preserve order. But you will see that order is preserved if you iterate or use the keys or values methods:

>> names = ['Amy Irving', 'Jane Doe', 'John Doe', 'John Updike', 'Susan Anthony']
>> ordered = names.group_by { |name| name.split.first }
=> #<OrderedHash {"John"=>["John Doe", "John Updike"], "Amy"=>["Amy Irving"], "Susan"=>["Susan Anthony"], "Jane"=>["Jane Doe"]}>

# (note that the inspect above is in undefined order)

>> ordered.keys                          # will be ordered properly
=> ["Amy", "Jane", "John", "Susan"]

>> ordered.each { |first, full| puts first; full.each { |name| puts "  #{name}" } }  # will be ordered properly
Amy
  Amy Irving
Jane
  Jane Doe
John
  John Doe
  John Updike
Susan
  Susan Anthony
October 26, 2012
0 thanks

#performed? is an option when getting ActionController::DoubleRenderError

You can avoid `ActionController::DoubleRenderError (Can only render or redirect once per action)` with `#performed?`

For example

def index
  redirect_to not_found_path unless authenticated?
  render :action => 'update' unless performed?
end
October 24, 2012
0 thanks

If you happen to face some weird rounding issue...

i.e.

helper.number_to_currency(187)
=> "190 kr"

check out your… translations! Especially ‘significant’ key… In my case it was

number:
   currency:
     format:
       significant: 'false'

that broke rounding. It should have been

number:
   currency:
     format:
       significant: ! 'false'

And now it works perfectly

helper.number_to_currency(187)
=> "187 kr"
October 24, 2012
1 thank

To add an ID to the form

Found this the hard way, but to add an ID to the form generated by form_tag, you must explicitly make hashes.

Add ID

<%= form_tag({:action => 'create'}, {:id => 'anID'}) %>
October 18, 2012
0 thanks

Showing the select with a value previously known

Enter the value in the ‘value to check if exist in the list’ section and the drop down should have that selected

Code example

select_tag "name",
options_for_select(list.collect{ [ text, value] },
            'value to check if exist in the list', 
            {:include_blank => true}
October 17, 2012
1 thank

See also: Rack::Utils.parse_nested_query.

Note that CGI::parse does not attempt to create a multi-level object; that is, it basically ignores hard brackets in key names.

For a method that does deal with these, see Rack::Utils.parse_nested_query.

October 10, 2012 - (>= v1_9_1_378)
0 thanks

Bad Example

@nZifnab it is a bad example because an included module is basically a class.

module Mod
    def exit(code = 0)
        puts "Exiting with code #{code}"
        super
    end
end

include Mod

exit 99

produces

Exiting with code 99
October 7, 2012
0 thanks

Send with filename

The Content-Disposition response header holds the suggested attachment filename (i.e. “attachment; filename=fname.ext”)

Set the :disposition option to pass this name.

Controller

http = Net::HTTP.new(@page.host)
res = http.post(path, info.to_query, headers)
send_data res, :content_type => res.content_type, :disposition => res["Content-Disposition"], status: res.code
October 2, 2012 - (v2.3.2 - v2.3.8)
0 thanks

Clarification with use of update_all

I would like to point out that if you are on rails 2.3.11 or lower you will not be able to run ledermann code.

Ledermann Code

user.messages.update_all(:read => true)

If you are running 2.3 or later it you will have to use James code

James Code

Message.update_all({:read => true}, {:id => user.messages})

thanks guys for all the code help

September 28, 2012 - (>= v3.0.0)
0 thanks

Don't mix attr_accessible and attr_protected within single class.

Don’t use constructs like this one, they won’t work:

class User < ActiveRecord::Base
  attr_accessible :name
  attr_protected :id, :password_digest, :created_at, :updated_at, as: :admin
end

Instead, use the same method for all roles:

class User < ActiveRecord::Base
  attr_accessible :name
  attr_accessible :name, :login, as: :admin
end

You may want to add following to your `/config/initializers`:

class ActiveRecord::Base
  class << self
    alias :original_inherited :inherited
    def inherited subclass
      original_inherited subclass
      subclass.attr_accessible
      subclass.attr_accessible(subclass.attribute_names.map(&:to_sym) - [:id, :created_at, :updated_at], as: :admin)
    end
  end
end
September 28, 2012
1 thank

Don't allow mass assignments on model

Replying to elfo’s comment, you can achieve it easier, just add following line to `/config/application.rb`.

config.active_record.whitelist_attributes = true

All attributes in all models will be mass assignment protected by default. You can still use attr_accessible or attr_protected to override it.

September 28, 2012 - (<= v2.3.8)
2 thanks

Skip validations

.

user.save(false)

will skip validations

September 19, 2012 - (v3.1.0 - v3.2.8)
0 thanks

Return value:

The result of this method is a hash of the following form:

{"table_field"=>"table value", "another_field" => 15, ...}

For example:

{"user_id"=>21}
September 16, 2012
This note might be spam Show
September 11, 2012 - (>= v3.1.0)
0 thanks

Custom serialization

It is possible to supply a class with own (de)serialization logic to the serialize call. Given object must respond to load and dump calls.

Following example serializes symbols into their string representation and store them in database as raw strings instead of their YAML representation, i.e. :pumpkin would be stored as ‘pumpkin’, and not as ‘--- :pumpkin\n’

Example

clas SomeModel < ActiveRecord::Base
  class SymbolWrapper
    def self.load(string)
      string.to_sym
    end

    def self.dump(symbol)
      symbol.to_s
    end
  end

  serialize :value, SymbolWrapper
end
September 10, 2012
0 thanks

Reports originally defined method names, not invoked names in Ruby 1.9.x

In Ruby 1.8.7, the reported method names were those of the methods actually invoked, so if #b was an alias for #a, and #b was called, it would be reported as “… in `b’”. In Ruby 1.9, the same invocation is now reported as “… in `a’”.

Unfortunately, this change disables the hack that could formerly be used to create a variant of __method__ that returns the method as actually invoked. The new __callee__ method is no help with that, because it is currently synonymous with __method__.