Recent notes
RSS feedThe 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 ?
What artemave said.
I’d remove my original note if I could, but I can’t see a way how.
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.
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.
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.
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
#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
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"
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'}) %>
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}
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.
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
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
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
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
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.
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}
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
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__.
__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.
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.
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
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
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”)+
Rails Guides
There is an excellent guide on the use of this method located here:
http://guides.rubyonrails.org/active_record_querying.html#conditions
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!
in rails3 StatusCodes have been moved to Rack::Utils
in rails3 StatusCodes have been moved to Rack::Utils