Flowdock

Recent notes

RSS feed
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__.

September 10, 2012
0 thanks

__callee__ and __method__ both return symbol when originally defined, not current

There has been some indication that __callee__ is intended to return the symbol with which the method was actually invoked, whereas __method__ returns name with which the method was originally defined, but __callee__ actually behaves identically to __method__ in Ruby 1.9.1 1.9.2, and 1.9.3.

This distinction is meaningful, because methods can be aliased after they are created.

In Ruby 1.8.7, it was possible (though) not convenient to get the name of the method as actually invoked, by calling another method that extracts the name from caller.first. Even that hack no longer works in Ruby 1.9 though, since it will return the originally defined method name as well.

September 5, 2012 - (v3.2.1 - v3.2.8)
1 thank

ActiveModel::MassAssignmentSecurity::Error

Note that in the example shown in the documentation, `user.assign_attributes({ :name => ‘Josh’, :is_admin => true })` would raise a `ActiveModel::MassAssignmentSecurity::Error` and would not actually update user.name, contrary to what the example seems to demonstrate.

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

Don't allow mass assignments on model

To block all mass assignments on a model, it’s as simple as having an empty list of accessible attributes.

example
class Users < ActiveRecord::Base
   attr_accessible #none
end
August 30, 2012
2 thanks

Usage

In Rails 3.X console:

Rails.application.routes.recognize_path('/my_path')
August 30, 2012
0 thanks

How to handle dynamic controller class evaluation based on params

Possible with following snippet of code (for instance if each branch has some different controller logic, but if the controller is not present, it should fallback to default controller).

Advantages are so we do not have to make blank inherited controllers and routes for them, to do it with plain inheritance.

class ActionDispatch::Routing::RouteSet::CustomDispatcher < ActionDispatch::Routing::RouteSet::Dispatcher
  # These are the controllers that we should attempt fallbacks on
  FALLBACK_CONTROLLERS = /customer\/branch\/(projects|events)$/

  def controller(params, default_controller=true)
    # This defines when we want to attempt fallbacks pattern
    super unless params[:branch_id] && params[:controller].try(:match, FALLBACK_CONTROLLERS)
    controller_param = params[:controller]

    # Having these supplied, we handle controller evaluation by our own method...
    controller_reference_with_fallbacks(params[:branch_id], controller_param)
  rescue NameError => e
    raise ActionController::RoutingError, e.message, e.backtrace if default_controller
  end

  private

  def controller_reference_with_fallbacks(branch_id, controller_param)
    # This is how fallbacks are evaluated       
    controller_name = "#{controller_param.sub('/branch', "/branch/#{branch_id}").camelize}Controller"

    controller = ActiveSupport::Dependencies.reference(controller_name)

    begin
      controller.get(controller_name)
    rescue NameError => e  # If there is no specific class for given branch, fallback to original class
      controller_reference(controller_param)
    end
  end
end

ActionDispatch::Routing::Mapper::Mapping.class_eval do
  private

  # We do overwrite dispatcher class, that is used to evaluate controller classes from params
  def app
    ActionDispatch::Routing::Mapper::Constraints.new(
        to.respond_to?(:call) ? to : ::ActionDispatch::Routing::RouteSet::CustomDispatcher.new(:defaults => defaults),
        blocks,
        @set.request_class
    )
  end
end
August 24, 2012
0 thanks

Specify :host option in emails

Emails need a fully qualified URL (with domain). Use the :host parameter.

But note also that you need to specify a value that is not dependent upon the request context. http://api.rubyonrails.org/classes/ActionMailer/Base.html recommends setting a default host in application.rb For those of us who have development, test, staging and production environments, set in the environment-specific files, or in the :default hash in the mailer.

This applies to both +url_for(:host => “example.com”)+ and when using named routes as in +widgets_url(:host => “example.com”)+

August 22, 2012 - (>= v3.0.0)
0 thanks

Rails Guides

There is an excellent guide on the use of this method located here:

http://guides.rubyonrails.org/active_record_querying.html#conditions

August 22, 2012 - (v3.2.8)
0 thanks

Using Amazon Simple Email Service with ActionMailer

First of all, get all the necessary SES credentials and verify your email address.

Then, just edit your config/environments/*.rb files:

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
    address: 'email-smtp.us-east-1.amazonaws.com',
    user_name: 'your-ses-smtp-user-name',
    password: 'your-ses-smtp-password',
    authentication: :login,
    enable_starttls_auto: true
}

And that’s it!

August 22, 2012
0 thanks

in rails3 StatusCodes have been moved to Rack::Utils

in rails3 StatusCodes have been moved to Rack::Utils

August 20, 2012
0 thanks

To use class attribute with a hash

You can use a setter with merge:

self.settings = settings.merge(key => value)
August 19, 2012
0 thanks

On destroying data

Reply to tvle83 and pgmcgee: the destructiveness of this method depends on your database. Some databases are better at converting between disparate types than others. For example, when changing a column from a numeric type to a string type, some databases drop the data where others will turn the numbers into their string representations.

Essentially, YMMV.

August 6, 2012
0 thanks

What it do?

For those favoring YAML outputs, this methods simply and recursively outputs the keys and values in YAML (into a String) for your pleasure.

August 3, 2012
0 thanks

a misprint?

In section ‘Bi-directional associations’ an example:

d = Dungeon.first

t = d.traps.first

d.level == t.dungeon.level # => true

d.level = 10

d.level == t.dungeon.level # => false

Then use has_many associations, but lower than written ‘for belongs_to associations has_many inverse associations are ignored.’

July 24, 2012
1 thank

rest of code is in Object#try

The logic for #try is shared between this method and Object#try – “Show source” here doesn’t show the whole story. Both methods are currently implemented in the file activesupport/lib/active_support/core_ext/object/try.rb .

July 24, 2012
1 thank

rest of code is in NilClass#try

If you click “Show source” here, you may get confused. The logic for #try is shared between this method and NilClass#try . Both versions are currently implemented in the file activesupport/lib/active_support/core_ext/object/try.rb .

July 23, 2012
1 thank

Long-wanted functional extension

This is pretty nice method allowing you to build stuff in a functional way.

Lets say you want to build a hash from an array, keyed by array object, where each value is the number of same objects in the array.

# imperative style :-P

h = Hash.new(0)
[1, 3, 2, 3, 1, 3].each { |i| h[i] += 1 }
h # => {1=>2, 3=>3, 2=>1} 

# functional style, using inject. Note that you need to explicitly return the accumulator in the end

[1, 3, 2, 3, 1, 3].inject(Hash.new(0)) { |a, i| a[i] += 1; a } 
# => {1=>2, 3=>3, 2=>1} 

# using each_with_object. Note the reversed block params - accumulator is the last parameter. 
# Mnemonic: consistent with each_with_index, where object is the first parameter

[1, 3, 2, 3, 1, 3].each_with_object(Hash.new(0)) {|i, a| a[i] += 1}
# => {1=>2, 3=>3, 2=>1} 
July 23, 2012
0 thanks

Replacement

Replacement

# Method using returning can replaced
def foo
  returning Hash.new do |h|
    h[:foo] = "bar"
  end
end
# By method using tap  
def foo
  Hash.new.tap do |h|
    h[:foo] = "bar"
  end
end
July 20, 2012
1 thank

Skipping validation - follow up

For Rails 2.x use #save(false) for Rails 3.x use #save(:validate => false)