Flowdock

Recent notes

RSS feed
November 3, 2015 - (>= v1_9_2_180)
0 thanks

close but no bananna

@tarasevich noted that

a.flat_map(&b) works exactly like a.map(&b).flatten!(1)

This is backwards because map and flatten are not always interchangeable in order. Mapping over the example array only gives you 2 items. This can result in significant differences depending on what you’re doing in the map. This is easier to demonstrate if we change the example to strings.

[["1","2"],["3","4"]].map {|i| i[0] } # => ["1", "3"]
[["1","2"],["3","4"]].map {|i| i[0] }.flatten  # => ["1", "3"]

BUT if you swap the order

[["1","2"],["3","4"]].flatten.map {|i| i[0] } # => ["1", "2", "3", "4"]

in order to remember what it is equivalent to just note that the method name is already in the correct order. flat_map -> flatten + map

November 3, 2015 - (v4.2.1)
0 thanks

Possible bug

Works as expected for non bang methods

>  a={x:1, y:2, z:3}                                                                      
=> {:x=>1, :y=>2, :z=>3}

> a.slice(:y)                                                                             
=> {:y=>2}

> a.except(:y)                                                                            
=> {:x=>1, :z=>3}

Bug on slice! it behaves like except!

> a.clone.slice!(:y)                                                                                                                                                                                
=> {:x=>1, :z=>3}

> a.clone.except!(:y)                                                                                                                                                                               
=> {:x=>1, :z=>3}

slice! should return {:y=>2} and modify a to no longer have it

October 19, 2015
0 thanks

Multiple files

To use multiple file upload need to use variable_name[].

like this:

file_field_tag 'files[]', :multiple => true  

and in controller:

if !params[ :files ].nil?
  params[ :files ].each{ |file|
     # do your staff
  }
end
October 13, 2015 - (>= v4.1.8)
0 thanks

"Class methods on your model are automatically available on scopes."

The final example above – “Class methods on your model are automatically available on scopes.” – contains a subtle but vital change from earlier versions of the doc – namely, “pluck” (current example) vs “map” (old example). The former works, the latter does not. See http://github.com/rails/rails/issues/21943 for confirmation that the old documentation is incorrect, and for a workaround.

(Spoiler alert: Use

all.map(&:title)

instead of just

map(&:title)

in order to achieve the same effect.)

October 13, 2015 - (>= v4.1.8)
0 thanks

"Class methods on your model are automatically available on scopes."

The final example above – “Class methods on your model are automatically available on scopes.” – does not work as written. See http://github.com/rails/rails/issues/21943 for confirmation that the old documentation is incorrect, and for a workaround.

(Spoiler alert: Use

all.map(&:title)

instead of just

map(&:title)

in order to achieve the same effect.)

October 5, 2015 - (>= v3.2.1)
0 thanks

arel_table order by

More objected way how to achieve ORDOR BY .… DESC is like this :

class User < ActiveRecord::Base
  has_many :status_changes

  def latest_status_change
    status_changes
     .order(StatusChange.arel_table['created_at'].desc)
     .first
  end
end

class StatusChange < ActiverRecord::Base
  belongs_to :user
end

resulting in:

SELECT "status_changes".* FROM "status_changes" WHERE "status_changes"."user_id" = 1 ORDER BY "status_changes"."created_at" DESC

Benefits:

  • you are strictly bound to Modelclass name => renaming table in model will not break the sql code (of if it will, it will explicitly break the syntax on Ruby level, not DB level)

  • you still have the benefit of explicitly saying what table.column the order should be

  • easier to re-factor parts to Query Objects

September 14, 2015 - (v1_9_1_378 - v1_9_3_392)
0 thanks

Getting the return value from the underlying method of an Enumerator

This is documented in the example code, but easy to miss.

When you get an Enumerator using #to_enum(:method_name, …), you can get all of the yielded values using #next, but not the value that is finally returned.

That value can be retrieved via the #result attribute of the StopIteration exception object that is raised when calling #next after the underlying method has returned.

September 9, 2015
1 thank

Warning: prevents persistence but doesn't prevent setting

For example:

class Widget < ActiveRecord::Base
  attr_readonly :key
end
w = Widget.create! key: 'foo'
w.update! key: 'bar'
w.key #=> 'bar'
w.reload.key #=> 'foo'
September 8, 2015
1 thank

Favicon generator

Hello, I suggest you to try this favicon generator and creator, http://onlinefavicon.com/ , you can create favicon using drawing tool or add picture jpg or other file and make 16x16 or 32x32 ICO file, also see the gallery with favicons from other users or download the same, at end you can read description how to set up favicon to your site!

August 25, 2015
0 thanks

Using Arel

You can also use Arel.

For example:

class ArticlePage < ActiveRecord::Base
  belongs_to :article
  scope :published, -> { where.not(published_at: nil) }
  scope :all_ready, -> { select("every(workflow_state = 'ready') AS is_ready") }
end

class Article < ActiveRecord::Base
  has_many :article_pages
  def all_ready?
    ActiveRecord::Base.select_values(article_pages.all_ready,published) = 't'
  end
end
August 18, 2015
0 thanks

Add method to instacne eval

We can add method to instance by using instance_eval.

Code example

string = "String"
string.instance_eval do
  def new_method
    self.reverse
  end
end

Output

irb(main):033:0> string.new_method
=> "gnirtS"
August 3, 2015
1 thank

define_method with default parameters

To define a method with a default parameter the usual notation can be used:

define_method("example") do |fixed, default = {}|
  # something
end
August 2, 2015
0 thanks

Skip validation

update_all : skip validations, and will save the object to the database regardless of its validity. They should be used with caution.

July 31, 2015
0 thanks

Also takes a block

You can define methods within a block

User = Struct.new(:first_name, :last_name) do
  def full_name
    "#{first_name} #{last_name}"
  end
end

user = User.new('Simon', 'Templar') # => #<struct User first_name="Simon", last_name="Templar">
user.full_name # => "Simon Templar"
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
1 thank

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 13, 2015
0 thanks

Correction to previous comment

You’ve misread the documentation, @sandyjoins. If you pass two arguments, the second one is a length argument, not an upper bound.

“Hello there”.byteslice(6, 1) == “t”

July 13, 2015 - (v1_9_3_392)
0 thanks

Important note!

Special cases:

Code example

Test”.byteslice(1, 3) => “est” #both limits inclusive

Test”.byteslice(0, 3) => “Tes” #upper limit exclusive

Test”.byteslice(0..3) => “Test” # Both limits inclusive

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 23, 2015 - (v1_9_3_392)
0 thanks

Constants

Reading source one can find detailed patterns: github.com/ruby/ruby/blob/ruby_1_9_3/lib/uri/common.rb

May 22, 2015 - (>= v1_8_6_287)
0 thanks

Not exactly like map {}.flatten

To also give dimension, is about 4.5 times faster then map {}.flatten.

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 12, 2015
0 thanks

RE: Convert an Array of Arrays to a Hash using inject

Another way to convert an array of arrays to a hash using inject:

array = [['A', 'a'], ['B', 'b'], ['C', 'c']]

hash = array.inject({}) do |memo, values|
  memo.merge!(values.first => values.last)
end

hash
# => {'A' => 'a', 'B' => 'b', 'C' => 'c'}