Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

has_many returns an array instead of ActiveRecord class

I am following OmniAuth railscasts and trying to implement the same with authlogic + facebook instead of devise + twitter as shown in the railscast.

Maybe my understanding of has_many still isn't good but in the railscasts ryan has the following code in AuthenticationsController

  def create
    auth = request.env["rack.auth"]
    current_user.authentications.find_or_create_by_provider_and_uid(auth['provider'], auth['uid'])
    flash[:notice] = "Authentication successful."
    redirect_to authentications_url
  end

In my implementation current_user.authentications returns an array [] how can I call find_or_create_by_provider_and_uid on an array?

Is my implementation wrong? Isn't has_many suppose to return an array?

Error I get is that I am calling find_or_create_by_provider_and_uid on a nil object.

current_user.authentications is nil well because the user does not have any authentications yet.

like image 366
Omnipresent Avatar asked Jun 02 '11 18:06

Omnipresent


1 Answers

The array is actually an AssociationProxy instance, which delegates all method calls to the internal object, which is an array in the case of a has_many association (also see this question). This means you should be able to call magic methods like find_or_create_by_provider_and_uid, as well as scopes etc. on it just fine.

I found this question because I stumbled over a similar problem: for some reason I couldn't call ActiveRecord::Relation#klass to find out the model class:

post.comments.klass # => NoMethodError

But by calling relation first you can get a normal ActiveRecord::Relation instance:

post.comments.relation.klass # => Comment
like image 88
toupeira Avatar answered Oct 11 '22 17:10

toupeira