Undefined method find or create by? #102

Closed
dfischer opened this Issue Sep 13, 2012 · 11 comments

Projects

None yet

6 participants

@dfischer

Just added to project:

User.find(1).add_role :admin
NoMethodError: undefined method `find_or_create_by' for #<Rolify::Adapter::ResourceAdapter:0x007fcc2fee7cf0>

Hmm?

@dfischer

Oh I know my issue.

I put resourcify on my user model as well. That blew it up. I wanted to do this because I wanted users to have roles over other users.

E.g User.find(1).add_role :manager, User.find(2)

I guess you can't do that. Anyone suggest a way to do this?

@EppO
Member
EppO commented Sep 17, 2012

Hi,
I've never tried it, but I think you can put rolify and resourcify methods in your User model, if you want to assign roles over other users. But don't forget rolify method as it provides the add_role method.

@EppO EppO was assigned Sep 17, 2012
@erwin16
erwin16 commented Oct 2, 2012

no you cannot have both ... I just tried it
creating an Admin w rolify only works,
but
creating an Admin w rolify and resourcify doesn't work

NoMethodError: undefined method find_or_create_by' for #<Rolify::Adapter::ResourceAdapter:0x007fdf61f1d180> from /Users/yves/.rvm/gems/ruby-1.9.3-p194@rails32/gems/rolify-3.2.0/lib/rolify/role.rb:12:inadd_role'

doesn't know if it's also raisng an error w Mongoid , but this error is clear enough w Activerecord
anyway to allow an (Admin / User) to have roles vs its sibblings ?

@erwin16
erwin16 commented Oct 2, 2012

I tried to understand what could be wrong .. maybe I cannot do the follwoing :
I have 2 separate classes w roles : User ( frontoffice) and Admin ( for backoffice)
I splited the tables migrations into 3 :

  • create roles table ( I can have only one table as I will have unique role names )
  • create users_roles table
  • create admins_roles table

I updated my Admin

class Admin < ActiveRecord::Base
rolify
resourcify

doesn't run ...
self.class.adapter
#<Rolify::Adapter::ResourceAdapter:0x007fc3a8eb6fe0 @role_cname="Role", @user_cname="Admin">
NoMethodError: undefined method `find_or_create_by' for #Rolify::Adapter::ResourceAdapter:0x007fc3a8eb6fe0

this is the key point !! resourcify SHOULD BE defined BEFORE rolify

class Admin < ActiveRecord::Base
resourcify
rolify

runs ... as in this case
self.class.adapter
#<Rolify::Adapter::RoleAdapter:0x007f844f880150 @role_cname="Role", @user_cname="Admin">

@jschlesser

I want to do the same thing which is both resourcify and rolify my user model.

I tried putting resourcify above rolify but I got a:

SystemStackError: stack level too deep

maybe I should post to stackoverflow ;) I do have one difference in my case, im using mongodb and mongoid. I dont get any helpful messages just that one liner.

@EppO
Member
EppO commented Oct 22, 2012

Ok, so ActiveRecord adapter looks like working if you declare resourcify and rolify in the good order but not Mongoid adapter. I'll investigate this.

@amer
Contributor
amer commented Nov 10, 2012

Basically the problem happens when the method user.roles is called, and that happens when we try to add a new role, more specifically in lib/rolify/adapters/mongoid/role_adapter.rb

def add(relation, role)
   relation.roles << role
end

When you add resourcify and rolify for the same model basically you are doing something like

class User
  include Mongoid::Document

  has_many :roles
  has_and_belongs_to_many :roles

  field :name, type: String
end

And that seems to cause a great deal of confusion for our friend Mongoid. I think that Mongoid is defining a new method but with a wrong name which probably caused an infinite recursion and that's resulted in a SystemStackError: stack level too deep.

I'm not sure but maybe this is a Mongoid bug, but for sure we can do something to work around it.

I hope this was useful.

@EppO
Member
EppO commented Dec 10, 2012

You are totally right. roles is already defined as an association in rolify method and resourcify defines another different roles association. I should add an argument to be able to tweak the association name in resourcify.
Thanks for the investigation.

@EppO EppO added a commit that referenced this issue Dec 10, 2012
@EppO EppO edited specs for #111 and #102
added specs for mongoid
1b24399
@EppO EppO added a commit that closed this issue Dec 10, 2012
@EppO EppO added optional argument on resourcify method to change the role assoc…
…iation name on the resource model

closes #102
db0a98f
@EppO EppO closed this in db0a98f Dec 10, 2012
@EppO
Member
EppO commented Dec 11, 2012

If you use master branch, you will be able to use rolify and resourcify in the User model class like this.
Please note that you have to use as argument of resourcify another association name than :roles because it's already used by rolify method. In that use case, this argument is mandatory.

@EppO
Member
EppO commented Dec 11, 2012

This fix will be included in rolify 3.3 release

@saizai
saizai commented Feb 6, 2014

Still broken on 3.4 w/ rolify + resourcify User model. Removing resourcify from User model fixed it.

> u.add_role :admin
NoMethodError: undefined method `find_or_create_by' for #<Rolify::Adapter::ResourceAdapter:0x000001017dbde0>
    from /Users/saizai/.rvm/gems/ruby-2.1.0/gems/rolify-3.4.0/lib/rolify/role.rb:12:in `add_role'
@EppO EppO was unassigned by dfischer Jul 3, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment