You should always specify the :inverse_of option on AR associations

Directly from ActiveRecord documentation on bi-directional associations:

Bi-directional associations

When you specify an association there is usually an association on the associated model that specifies the same relationship in reverse. For example, with the following models:

class Dungeon < ActiveRecord::Base
  has_many :traps
  has_one :evil_wizard
end

class Trap < ActiveRecord::Base
  belongs_to :dungeon
end

class EvilWizard < ActiveRecord::Base
  belongs_to :dungeon
end

The traps association on Dungeon and the dungeon association on Trap are the inverse of each other and the inverse of the dungeon association on EvilWizard is the evil_wizard association on Dungeon (and vice-versa). By default, Active Record doesn’t know anything about these inverse relationships and so no object loading optimization is possible. For example:

d = Dungeon.first
t = d.traps.first
d.level == t.dungeon.level # => true
d.level = 10
d.level == t.dungeon.level # => false

The Dungeon instances d and t.dungeon in the above example refer to the same object data from the database, but are actually different in-memory copies of that data. **Specifying the :inverse_of option on associations lets you tell Active Record about inverse relationships and it will optimise object loading. For example, if we changed our model definitions to:

class Dungeon < ActiveRecord::Base
  has_many :traps, inverse_of: :dungeon
  has_one :evil_wizard, inverse_of: :dungeon
end

class Trap < ActiveRecord::Base
  belongs_to :dungeon, inverse_of: :traps
end

class EvilWizard < ActiveRecord::Base
  belongs_to :dungeon, inverse_of: :evil_wizard
end

Then, from our code snippet above, d and t.dungeon are actually the same in-memory instance and our final d.level == t.dungeon.level will return true.

There are limitations to :inverse_of support:

  • does not work with :through associations.
  • does not work with :polymorphic associations.
  • for belongs_to associations has_many inverse associations are ignored.

Heroku Websockets

One month ago Heroku [announced websocket support](Websockets in public beta on Heroku).

If you need a pub/sub solution, Pusher remains an unbeatable alternative: its free plan is good for small apps, and you can setup it in seconds.

But if you need a classic client-server solution (i.e. to talk to each client separately) there were no chances to develop it on Heroku.

Now it should be easy enough to achieve this. You can find the official guide for ruby here.

And if you are wondering about performances, read this.

Did you know they changed #try ?

Did you know #try has been changed since Rails 4? I didn’t.

Look at the implementation for Rails 4 and Rails 3. Rails 4 implementation uses respond_to? to check the method presence before calling it via send. It’s a subtle change, but it’s enough to become a problem: In Rails 3 you could use try even when you are dealing with method_missing. Now you have to override the respond_to? to make it work. E.g.:

class A
  def method_missing name, *args, &block
    if name.to_s == 'foo'
      'bar'
    else
      super
    end
  end

  def respond_to? name
    name.to_s == 'foo' || super
  end
end

A.new.try :foo # this returns nil if we don't override #respond_to?

Stop writing JavaScript and get back to Ruby!

Cross posted from: Eliæ

Remeber that feeling that you had after having tried CoffeeScript getting back to a project with plain JavaScript and felt so constricted?

Well, after re-writing a couple of coffee classes with OpalRuby I felt exactly that way, and with 14.9KB of footprint (min+gz, jQuery is 32KB) is a complete no brainer.

So let’s gobble up our first chunk of code, that will salute from the browser console:

puts 'hi buddies!'

You wonder how that gets translated?

Fear that it will look like this?

'egin',cb='bootstrap',u='clear.cache.gif',z='content',bc='end',lb='gecko',mb='g
cko1_8',yb='gwt.hybrid',xb='gwt/standard/standard.css',E='gwt:onLoadErrorFn',B=
'gwt:onPropertyErrorFn',y='gwt:property',Db='head',qb='hosted.html?hello',Cb='h
ref',kb='ie6',ab='iframe',t='img',bb="javascript:''",zb='link',pb='loadExternal
Refs',v='meta',eb='moduleRequested',ac='moduleStartup',jb='msie',w='name',gb='o
pera',db='position:absolute;width:0;height:0;border:none',Ab='rel',ib='safari',
rb='selectingPermutation',x='startup',m='hello',Bb='stylesheet',ob='unknown',fb
='user.agent',hb='webkit';var fc=window,k=document,ec=fc.__gwtStatsEvent?functi
on(a){return fc.__gwtStatsEvent(a)}:null,zc,pc,kc,jc=l,sc={},Cc=[],yc=[],ic=[],
vc,xc;ec&&ec({moduleName:m,subSystem:x,evtGroup:cb,millis:(new Date()).getTime(
),type:nb});if(!fc.__gwt_stylesLoaded){fc.__gwt_stylesLoaded={}}if(!fc.__gwt_sc
riptsLoaded){fc.__gwt_scriptsLoaded={}}function oc(){var b=false;try{b=fc.exter

Nope! it’s Chuck Testa

(function() {
  return this.$puts("hi buddies!")
}).call(Opal.top);

But it will be obviously a mess to integrate it with existing javascript!!1

Let’s how to add #next and #prev to the Element class:

class Element
  def next(selector = '')
    element = nil
    `element = jQuery(this.el).next(selector)[0] || nil;`
    Element.new element if element
  end
end

But I’m on Rails!

Here you served:

gem 'opal-rails'

Which il provide you a requirable libraries for application.js

//= require opal
//= require rquery

and the .opal extension for your files

# app/assets/javascripts/hi-world.js.opal

puts "G'day world!"

A template handler:

# app/views/posts/show.js.opal.erb

Element.id('<%= dom_id @post %>').show

and a Haml filter!

-# app/views/posts/show.html.haml

%article= post.body

%a#show-comments Display Comments!

.comments(style="display:none;")
  - post.comments.each do |comment|
    .comment= comment.body

:opal
  Document.ready? do
    Element.id('show-comments').on :click do
      Element.find('.comments').first.show
      false # aka preventDefault
    end
  end

Chaining the hell out of ActiveRecord models

So, you want a quick and dirty way to obtain all the models in your Rails app that contain relations targeting a collection (like an has_many relation)?

Dir['app/models/**/*.rb']
  .map {|model| File.basename(model, '.rb')}
  .map(&:camelize)
  .map(&:constantize)
  .select {|section|
    section.reflections.find {|name, reflection|
      reflection.collection?
    }
  }.map(&:to_s)

Demeter law?

You got served

kind of.. ^_^

Returning only an HTTP status code

If your making an API and some methods of your controller doesn’t need to render anything peculiar, you could rely on the head method.

head :ok

For an exhaustive list of the rails mapping you can use the handy cheat gem, created by Josh Susser.

$ gem install cheat
$ cheat status_codes
status_codes:
  Use these codes for the #head or #render methods.  ex:
    head :ok
    render :file => '404.html.erb', :status => :not_found
  
status_codes:
  Use these codes for the #head or #render methods.  ex:
    head :ok
    render :file => '404.html.erb', :status => :not_found
  
  1xx Informational
  
  100 => :continue
  101 => :switching_protocols
  102 => :processing
  
  2xx Success
  
  200 => :ok
...