Flowdock

Notes posted to Ruby on Rails

RSS feed
July 16, 2015
0 thanks

I would just use a validation instead of (the probably removed) :required

Just make sure you validate the presence of the association and not the foreign key, otherwise it will not work on new records.

The down side is that it will require the record in the cache, and will make a query otherwise. You can add `unless: :<foreign_key>?` If that’s a problem for you.

July 16, 2015
0 thanks

Is :required still valid ?

I get this error when using :required => true

ArgumentError: Unknown key: :required. Valid keys are: :class_name, :class, :foreign_key, :validate, :autosave, :remote, :dependent, :primary_key, :inverse_of, :foreign_type, :polymorphic, :touch, :counter_cache

Is :required not a valid key anymore ?

July 6, 2015
0 thanks

For supported arguments, see see match

As of July, 2015, the v4.2.1 doc says “see match[rdoc-ref:Base#match]” without a URL. I think you want this one: http://apidock.com/rails/ActionDispatch/Routing/Mapper/Base/match

July 2, 2015
0 thanks

Usage with enum

With enum fields you must use integer values:

code

Model.update_all(type: Model.types[specific_type])
July 1, 2015
0 thanks

Space before the opening [

In this example

Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]

The array is a parameter, so a space is required before the opening [, which is equivalent to write like this

Post.find_by_sql(["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date])
June 19, 2015
1 thank

Use :where or any defined scope before :find_or_create_by

You can chain find_or_create_by with :where, or any custom scope.

E.g.:

User.where(girls: true).find_or_create_by(first_name: ‘Scarlett’)


scope :celebrities, -> { where(celebrity: true) }

User.celebrities.create_with(last_name: ‘Johansson’).find_or_create_by(first_name: ‘Scarlett’)

June 9, 2015 - (v1.0.0 - v4.2.1)
0 thanks

Not a one-to-one-relationship

It’s incorrect to state that belongs_to “Specifies a one-to-one association with another class”.

If the inverse association is has_one then the model specifying belongs_to is the LHS of a zero/one-to-one relationship.

If the inverse association is has_many then the model specifying belongs_to is the LHS of a zero/many-to-one relationship.

Unless you know what the inverse association is, all you can assume is that instances of a class specifying a belongs_to association can be related to at most a single instance of the other class.

June 3, 2015 - (v4.0.2 - v4.2.1)
0 thanks

render with variables

perient view

Code example

<%= render 'time_select', locals: { select_name: 'from_tiem'}%>

render view

Code example

<%= locals[:select_name] %>

not:

Code example

<%= local_assigns[:select_name] %> 
May 18, 2015
0 thanks

Are those supported versions correct?

It seems like this method was supported in versions prior to 4.0.2.

UPDATE never mind, wish I could delete this comment..

May 8, 2015 - (>= v4.0.2)
0 thanks

This doesn't write files

This doesn’t write files, at least not anymore. Since at least rails 4 `Rack::Cache` isn’t included by default. In any case this method only ever set headers on the response.

April 23, 2015
0 thanks

add index directly

You can add an index now directly on the foreign_key :

t.references(:user, index: true)
April 14, 2015
0 thanks

Deprecation

It still exists but you give it a block instead of creating a method:

<=2.3.8

def before_create
  self.login = self.first_name
end

Now

before_create :set_login

def set_login
  self.login = self.first_name
end
April 8, 2015 - (v3.1.0 - v4.1.8)
0 thanks

What object_name.method values will result in checked chekboxes.

*It’s intended that method returns an integer and if that integer is above zero, then the checkbox is checked.* - more exactly, that’s how it’s determined whether value will be checked or not:

(`@checked_value` is checked_value, `value` is what object_name.method returns)

def checked?(value)
  case value
  when TrueClass, FalseClass 
    value == !!@checked_value
  when NilClass
    false
  when String
    value == @checked_value
  else
    if value.respond_to?(:include?)
      value.include?(@checked_value)
    else
      value.to_i == @checked_value.to_i
    end
  end
end
April 1, 2015 - (>= v4.1.8)
0 thanks

Parent associations are kept

Maybe this information will save you some time: parent associations (i.e. associations with foreign id in current record) are copied. Don’t assume you’ll get a safely editable object.

March 30, 2015
0 thanks

Passing a block does not behave as expected

When the condition is true, the block is not rendered:

<%= link_to_if true, users_path, {}, {} do %>
  <i class='fa fa-star'></i>
<% end %>

renders:

<a href="/users">/users</a>

But if the condition is false, the block will render:

<%= link_to_if false, users_path, {}, {} do %>
  <i class='fa fa-star'></i>
<% end %>

renders:

<i class='fa fa-star'></i>
March 30, 2015
0 thanks

If condition is false, options hash is ignored

Here, the class will be ignored:

<%= link_to_if false, 'Home', root_path, class: 'link' %> 
#=> Home
March 26, 2015
0 thanks

Save yourself a little typing

We often have a form with a select box that selects a model association. So for example to select a colour, when there is an associated Colour model, a select box will typically select :colour_id.

In this case, ActionView automatically humanizes :colour_id to produce “Colour” as the label text.

March 19, 2015
0 thanks

Wrong number of arguments (2 for 1)

If you get this error, wrap brackets with parentheses: Post.find_by_sql([“some query”])

March 19, 2015 - (v4.0.2)
0 thanks

number_field tag does not accept the same options as text_field_tag

number_field_tag does not accept the size or maxlength options; the max option for number_field_tag is used to control the size of the field. According to W3 http://www.w3.org/TR/html-markup/input.number.html , placeholder should be accepted, but I don’t find that this works in the way it works for text_field_tag.

March 18, 2015
0 thanks

Transactions and Stale ORM Data

Consider the following:

foo = Foo.new
bar = Bar.new

ActiveRecord::Base.transaction do
  foo.save! # succeeds
  bar.save! # failure, validation problem
end

foo.persisted? # true (!)

foo was not permanently stored in the database, but it was transiently saved, and this is reflected in the ActiveRecord model still in memory. But if you try

foo.reload # raises ActiveRecord::RecordNotFound

Don’t let stale data confuse you after using transactions!

Edited to add: This particular example does not succeed in reproducing the issue I encountered, which involved a slightly more complicated set of nested transactions. I haven’t managed to produce a simple test case where stale data remains in the model, but I have definitely experienced it in my app.

March 18, 2015
0 thanks

Transactions and Stale ORM Data

Consider the following:

ActiveRecord::Base.transaction do
  foo = Foo.new
  foo.save # succeeds

  bar = Bar.new
  bar.save # failure, validation problem
end
March 17, 2015 - (v2.1.0 - v3.2.13)
0 thanks
February 18, 2015
0 thanks

Not only for strings, but arrays and hashes too

exclude? is defined as !include?, meaning it is the exact opposite of include? . See the source.

This means that it works for Arrays and Hashes too, as well as for Strings.

It works for Arrays:

>> [nil].exclude?(nil)
=> false
>> [nil].include?(nil)
=> true
>> ["lala"].include?(nil)
=> false
>> ["lala"].exclude?(nil)
=> true

And for Hashes:

>> params = {}
=> {}
>> params[:db] = "lol"
=> "lol"
>> params.exclude?(:db)
=> false
>> params.include?(:db)
=> true
>> 
February 12, 2015
0 thanks

reorder

adding to stevo’s comment that reorder is also usefull when you have default scope in your model. eg: default_scope -> { order(created_at: :desc) }

February 11, 2015
0 thanks

Redirect to subdomain

If you’re looking to redirect to a subdomain you can do things like this:

redirect_to users_url(1, params: {a: :b}, subdomain: 'bob')
February 11, 2015
0 thanks

Why is this deprecated?

Anyone knows?

February 8, 2015
0 thanks

prepend_before_filter

If you need the method to be called at *the beginning* of the before_filter chain then you should use:

prepend_before_filter

February 3, 2015
0 thanks

Poor man's maybe

After creating a simple Maybe monad in Ruby, a colleaque noticed I could have just used try (I wasn’t aware try supports blocks). I think the method was even meant for such cases.

Why I mention this? Because it clarifies the whole ‘raises exception if method does not exist’ thing. It should not be crappy solution to exception handling, but allow for doing away with messy if statements. An example:

report = params[:query_type]
.try { |qt| build_query(qt) }
.try { |sql| run_query(sql) }
.try { |res| format_result(res) }

If any of the expressions params[], build_query, run_query etc. returns nil, the chain is halted and nil is returned. It still throws exceptions if a values is not nil and method does not exist, which is just like it should.