Question

I have three model objects in my rails app, User, Member, Team, where Member is my join table. Some member objects can be admins of a specific team, in my Member model I therefore have an admin bool attribute. In some of my views I want to check whether the current_user is an admin of any specific team.

My relevant team model looks like this:

has_many :members, after_add: :set_admin
has_many :users, through: :members
has_many :admins, -> { where("admin = 1") }, through: :members, source: :user

def set_admin

  self.members.first.admin = true

end

I want the user that creates the team to be an admin, therefore my set_admin method. Let me know if there is a better way to do it.

In my view I would like to do something like (HAML):

- if @team.admins.include?(current_user)
    ...

But this doesn't work. I'm not quite sure wether it is because the admin property doesn't get set. Or if there is some other problem, I'm not sure that .include?(current_user) works.

Any idea on what I can do?

update

This is how I create users and teams. In my UsersController I have:

# GET /users/new
def new
  @user = User.new
  @team = @user.teams.build
end

In my user model I have:

accepts_nested_attributes_for :teams

When user's signs up I also creates teams.

Was it helpful?

Solution

On Member define

class Member
  belongs_to :user
  belongs_to :team

  def self.admin
    where(:admin => 1)
  end
end

Then you can write

@team.members.admin

which will give you the list of all admin members (not users).

And then, you can add the following method on Team

def is_admin(user)
  self.members.admin.where(:user_id => user.id).count == 1
end

[UPDATE] You do set the admin flag, but is never saved. So your method should like

def set_admin
  if self.members.admin.count == 0
    self.members.first.update_atributes admin: 1
  end
end

I also test if there already is an admin, and only set it if not. otherwise you will set the first member to admin every time a member is added. But it is possible that is what you want.

UI/UX wise i would not like a random member becoming the admin, but rather the team creator immediately has to assign a team admin, upon creation of the team.

[UPDATE 2] You define the set_admin method on the association members of team, yet you do not use that relation to build the member, so that method is never triggered. You could have easily verified this by adding a log-method.

You create a user, with a new team, so you could add a method on the teams association. But this seems a little superfluous to me: you know which team you are adding, and which user.

In your controller you will have something like (just guessing)

user.save

which will create the user and the nested team, and by definition, the member in between. I would go for the explicit approach.

Option 1: after the save, add this line

user.members.last.update_attributes admin: true

since the last-added member-relation is the one just created. This feels a little dirty though.

Option 2: after the save, add this line

user.teams.last.set_admin

This reads a little nicer. So and then you can remove the after_add: :set_admin option, since the admin flag is set correctly on creation, and will not be needed when new members are added.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top