views:

63

answers:

2

I have the following line of Rails 3

In the project.rb model this works great:

permissions.find_by_project_id(1).role.name

However in a projects_helper it errors "undefined method `role' for nil:NilClass":

if Permission.find_by_project_id(project_id).role.name.nil?
.
.

Why is that?

What I really want is:

current_user.permission.find_by_project_id(project_id).role.name.nil?

But that errors: "undefined method `permission' for #"

Can you help me understand ActiveRecord allowing me to build these queries?

Thanks

added info:

permission.rb

class Permission < ActiveRecord::Base
    belongs_to :user 
    belongs_to :project 
    belongs_to :role 
end

project.rb

class Project < ActiveRecord::Base

    has_many :permissions
    has_many :users, :through => :permissions

end

role.rb

class Role < ActiveRecord::Base
    has_many :permissions
end

user.rb

class User < ActiveRecord::Base

    belongs_to :instance
    has_many :books
    has_many :permissions
    has_many :projects, :through => :permissions
+2  A: 

It looks like role is not set for the given project. You can work around it by:

current_user.permissions.find_by_project_id(project_id).role.try(:name).nil?
KandadaBoggu
I still get: undefined method `permission' for even though I have permission.rb... class Permission < ActiveRecord::Base belongs_to :user belongs_to :project belongs_to :role end
AnApprentice
There was typo in my code. Check the answer again.
KandadaBoggu
Thanks but it appears to be a bigger issue that captaintokyo pointed out above.
AnApprentice
+1  A: 

There must be a more elegant way to write this, so feel free to suggest improvements. The point is that you have to check first that project is not nil before you can do something with project.role.

def team_member?(project_id, current_user)
  project = current_user.permissions.find_by_project_id(project_id)

  if !project.nil? && !project.role.nil?
    # your code
  else
    # return false?
  end
end
captaintokyo
Thanks for helping me learn this, it's been tough... I just tried "Permission.find_by_project_id(1).role.name.nil?" and that does work, but it's not adding "user_id" to the query so it's to generic.
AnApprentice
When I try the function listed above,,, I get "undefined method `permission' for #<User:0x10341ce78>"
AnApprentice
If I try "if current_user.permissions.find_by_project_id(project_id).role.name.nil?" I get "undefined method `role' for nil:NilClass"
AnApprentice
This "if current_user.permissions.find_by_project_id(project_id).nil?" has the query a lot closer, "SELECT "permissions".* FROM "permissions" WHERE ("permissions".user_id = 1) AND ("permissions"."project_id" = 3) LIMIT 1" it's just not joining the Roles table and providing roles.name
AnApprentice
@captaintokyo, yes the user.rb has the following: belongs_to :instance has_many :books has_many :permissions has_many :projects, :through => :permissions attr_accessible :email, :password, :password_confirmation, :remember_me
AnApprentice
Hey, I just spotted the mistake. It should be `permissions` instead of `permission`. I updated the answer.
captaintokyo
@captaintokyo, thanks, see the above thread I left... that works but role.name is not working
AnApprentice
My last comment wasn't correct.. `find_by_project_id` should return 0 or 1 `permission(s)`, what is the exact error message you get on `role.name`?
captaintokyo
Did you try KandadaBoggu's suggestion with what I suggested above?
captaintokyo
"if Permission.find_by_project_id(1).role.name.nil?" doesn't return an error, but it doesn't has the user_id in the query, from the log " CACHE (0.0ms) SELECT "permissions".* FROM "permissions" WHERE ("permissions"."project_id" = 1) LIMIT 1 CACHE (0.0ms) SELECT "roles".* FROM "roles" WHERE ("roles"."id" = 1) LIMIT 1" ....................but if I update that to take the dynamic project_id, instead of hardcoding 1, "if Permission.find_by_project_id(project_id).role.name.nil?" then it errors: "undefined method `role' for nil:NilClass"
AnApprentice
I did try KandadaBoggu's suggestion, updating it to permissions and not permission. It still gives "undefined method `role' for nil:NilClass"
AnApprentice
I just told you it should be `permissions` not `permission`! Try `current_user.permissions.find_by_project_id(project_id).role.try(:name).nil?`
captaintokyo
@captaintokyo, my bad, I caught that after I commented and then edited. I did update to permissions with an S and it gives the error "undefined method `role' for nil:NilClass" do you have AIM?
AnApprentice
ok, what `project_id` are passing to the function? Does that `project` have any `permissions`??
captaintokyo
in my controller I have "def index @projects = Project.all ..." Then in my VIEW I have <% @projects.each do |project| %>... <% if team_member?(project.id, current_user) %> .... <% end %>
AnApprentice
Looks like you have the parameters in the wrong order... does this work? `if team_member?(current_user, project.id)`
captaintokyo
I actually had that matched up on my end... I sync'd it up to the above, and it still gives "undefined method `role' for nil:NilClass" I'm going to update the question above with my models... Maybe that's the problem?
AnApprentice
Ok models added, perhaps that's the problem?
AnApprentice
Hm, I think the problem is that there are projects that the `current_user` doesn't have `permissions` to. Then when you do `current_users.permissions.find_by_project_id()` it will return `nil`. First you have to check if `current_users.permissions.find_by_project_id()` is not null, then you can execute the rest of your code. I'll update my answer one more time, after that I going for a jog ;-)
captaintokyo
LOL, next time your in the bay area let me know, I owe you a beer
AnApprentice
Based on your last comment, I checked the database, and made all the permissions assigned to the user I'm logged in with, and that didn't fix it. WHAT DID fix it was having a permission for every project.. So the problem has been that if a permission doesn't exist for a project it breaks. Does that help?
AnApprentice
OK... I think with my updated answer it should work even if there are projects without permissions. I will check back later. Good luck.
captaintokyo
Ah man, sadly this is still not working... While the code doesn't error, This "project.role.name.nil?" isn't working, so it's always returnign false. "project.role.name.nil?" doesn't ever work.
AnApprentice
Hm, could you explain *why* you are checking if `role.name` is `nil`?
captaintokyo
captaintokyo
Tried that to, no luck. Something with project.role is not working.......... Tables: permissions (project_id, role_id, user_id), projects (id, name, creator,..), roles (id, name) Is the ActiveRecord belongs_to, has_many, etc... look ok? I can't help but think that's the problem with the project.role not working through out all this...
AnApprentice
Notice the exclamation mark in front of `project.role.nil?`. In the original version there is no exclamation mark. Did you try with the exclamation mark? Don't know about the data in your tables, but the relations look OK. The only thing I find strange is that projects have roles. I would think, a user has a role. I can't really judge about this, cause I don't know the specification for your system.
captaintokyo
@captain that did it, thanks!!! I can then use the helper to pass the role name to the view "@rolename = project.role.name"... Might be good to update your answer with the correction as it could help others. Thanks!
AnApprentice