Notes posted to Ruby on Rails
RSS feedUsing fontawesome icons inside link_to
<%= link_to (‘<i class=“fa fa-thumbs-up fa-lg”> </i>’).html_safe, vote_path(@image)%>
in this way you can use thumbs-up icon instead of usual text such as “like” in link_to
4.0.2 support
Where did this go in 4.0.2?
form_for with namescope and polymorphic path
<%= form_for([:namescope_name, @object], :url => polymorphic_path([:namescope_name, @objectable, @object])) do |form| %>
for the routes.
namescope :admin do
resources :articles do resources :comments end resources :photos do resources :comments end
end
<%= form_for([:admin, @comment], :url => polymorphic_path([:admin, @commentable, @comment])) do |form| %>
Note : @commentable = find_commentable
change_column did the trick for me
Use change_column, and make sure to specify the datatype:
class ChangeUsers < ActiveRecord::Migration def up change_column :users, :is_vote_reminder, :boolean, :default => true end end
Use this for has_one associations instead
I have confirmed that validates_associated doesn’t work with has_one associations, like @amasses said.
This however worked for me, so I recommend to use validates on the has_one association directly, like this:
class Book < ActiveRecord::Base has_one :cover, validates: true end
URI Module
Uniform handling of handling URIs
Flexibility to introduce custom URI schemes
Flexibility to have an alternate URI::Parser
For Example
require ‘uri’
uri = URI(“http://test.com/posts?id=30&limit=5#time=1305298413”)
uri.scheme #=> “http”
uri.host #=> “test.com”
uri.path #=> “/posts”
time is represented in the Rails app's timezone
From the description of Time.current (which is a Rails extension of Ruby’s native Time class)
“Returns Time.zone.now when Time.zone or config.time_zone are set, otherwise just returns Time.now.”
so 3.days.ago, for example, is in the application’s configured timezone (if it’s configured).
Reject If
reject_if: proc { |attributes| attributes[‘name’].blank? } Has saved me after an 3 hours of google search. Thanks
Alternitive to to add flash to respond with
This is a nice way to add flash if you don’t have a any logic that needs to go around your flash.
def destroy @current_user_session.destroy respond_with @current_user_session do |format| format.html {redirect_to login_path, notice: "You have been logged out"} end end
Original URL Example
# get “/articles?page=2”
request.original_url # => “http://www.example.com/articles?page=2”
You can add if: :query_method and unless: :query_method
You can make the callback conditional:
before_save :before_method, if: :needs_before_method? private def needs_before_method? false end def before_method # .. end
How to set request parameters (rails 3.2)
In Rails 3.2, this seems to work to create a TestRequest based on a certain url:
ActionController::TestRequest.new( Rack::MockRequest.env_for("http://something.tld/foo?one=two&three=four") )
Example Regex format matching
for phone and email
validates_format_of :phone, with: /\A(\d{10}|\(?\d{3}\)?[-. ]\d{3}[-.]\d{4})\z/ validates_format_of :email, with: /\A[\w]([^@\s,;]+)@(([\w-]+\.)+(com|edu|org|net|gov|mil|biz|info))\z/i
another way
Perhaps a more efficient way:
def create @post = Post.new(post_params) if @post.save redirect_to @post, notice: "The post #{@post.title} was added to the system." else render action: 'new' end end
where post_params is:
private def post_params params.require(:post).permit(..attributes to permit..) end
Security
In regards to @aamer’s comment on including the password salt this is a bad idea. `ActiveSupport::MessageVerifier` is NOT encrypted so:
verifier = ActiveSupport::MessageVerifier.new('secret') id = 'id' salt = 'salt' verifier.generate("#{id}-#{salt}") # "BAhJIgxpZC1zYWx0BjoGRVQ=--c880254708d18ce4a686bcd96a25cf0d2117e1e0" Base64.decode64(token.split("--").first) # "...id-salt..."
Note how the salt and id are both exposed! Instead a different token (reset_passowrd_token) should be used.
Passing an array of keys to exclude.
Use the “*” before passing the array in. For example:
PARAMS_TO_SCRUB = [ :created_at, :updated, :id, :format ] params.except!( *PARAMS_TO_SCRUB )
First example's output is incorrect
Everything except the initially html_safe input should be escaped in the output.
The output of the first example should be:
# => "<p>foo</p><br /><p>bar</p>"
Does not symbolize hashes in nested arrays
If you have a nested structure containing arrays of hashes, you still need to do that on your own, eg.
module SymbolizeHelper def symbolize_recursive(hash) {}.tap do |h| hash.each { |key, value| h[key.to_sym] = map_value(value) } end end def map_value(thing) case thing when Hash symbolize_recursive(thing) when Array thing.map { |v| map_value(v) } else thing end end end
Or, if you want to get really fancy with Ruby refinements (YMMV), one could do
module SymbolizeHelper extend self def symbolize_recursive(hash) {}.tap do |h| hash.each { |key, value| h[key.to_sym] = transform(value) } end end private def transform(thing) case thing when Hash; symbolize_recursive(thing) when Array; thing.map { |v| transform(v) } else; thing end end refine Hash do def deep_symbolize_keys SymbolizeHelper.symbolize_recursive(self) end end end
And later say
using SymbolizeHelper # augmented Hash#deep_symbolize_keys is now available
Does not work with ActionController::BadRequest
This method will not work with ActionController::BadRequest
Compatible with old docs
Library is moved, so old library documentation is compatible http://apidock.com/rails/v3.0.9/ActionController/Streaming/send_file
You could pass a range as the choices parameter
select :object, :method, (1..5)
Requires inheritance of ActionController::Metal
The example code will not work unless class inherits from ActionController::Metal (to get functioning controller) or at least AbstractController:Base.
link_to_if when URL helpers will throw an exception when condition fails
You can use an array to build a URL instead of a URL helper (e.g. edit_admin_user_path(event.user), which would fail when an event has no user:
link_to_if event.user, event.user_name, [:edit, :admin, event.user]
Sometimes, you need the "Oxford comma"
Re: Gramatical error
We invited the strippers, JFK, and Stalin.
versus the appositive phrase:
We invited the strippers, JFK and Stalin.
(Really, you need to see the comic to appreciate the difference.)
Grammatical error
Hi - not sure where I would submit this so just putting here. My apologies if not in the right place.
default: “, and ” - this is grammatically wrong. There should be no comma with the last and.
Example:
[‘one’, ‘two’, ‘three’].to_sentence
should give: “one, two and three”
There is no ‘ .… , and ’ which is considered grammatically incorrect I feel. The ‘and’ does it’s job in the English language quite well by joining the two words it’s in between.
Thank you.
Update for Rails 4
In the example
select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, { include_blank: true })
It can be updated to
select("post", "person_id", Person.pluck(:name, :id), { include_blank: true })
gives a parameter
As a note, you can use it like this:
after_save {|instance|
}
it will pass in the instance being saved.
form_for with :path route
Similar to danwich’s note, if you specify a route using the :path option
resource :posts, path: 'articles'
then the form_for tag must specify the :url option
form_for(@post), url: post_path(@post)
missing :through option
So the way to do the equivalent of a has_many :through is to use has_one :through, with the expected names.
so using the other example we could do
eg
class Person < ActiveRecord::Base belongs_to :team ... end class Task < ActiveRecord::Base belongs_to :person has_one :team, :through => :person end