Rails 4 - 通过多对多属性查找实体

时间:2014-05-13 19:45:17

标签: ruby-on-rails ruby-on-rails-4 many-to-many jointable

我的rails应用中有三个模型对象,UserMemberTeam,其中Member是我的联接表。某些成员对象可以是特定团队的管理员,在我的Member模型中,因此我有一个admin bool属性。在我的一些观点中,我想检查current_user是否是任何特定团队的管理员。

我的相关团队模型如下所示:

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

我希望创建团队的用户是管理员,因此我的set_admin方法。如果有更好的方法,请告诉我。

在我看来,我想做一些像(HAML)这样的事情:

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

但这不起作用。我不太确定它是否因为admin属性没有设置。或者如果还有其他问题,我不确定.include?(current_user)是否有效。

关于我能做什么的任何想法?

更新

这就是我创建用户和团队的方式。在我的UsersController我有:

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

在我的用户模型中,我有:

accepts_nested_attributes_for :teams

当用户注册时,我也会创建团队。

1 个答案:

答案 0 :(得分:1)

Member定义

class Member
  belongs_to :user
  belongs_to :team

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

然后你可以写

@team.members.admin

将为您提供所有管理员(非用户)的列表。

然后,您可以在Team

上添加以下方法
def is_admin(user)
  self.members.admin.where(:user_id => user.id).count == 1
end

[更新] 您设置了admin标志,但从未保存。所以你的方法应该是

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

我还测试是否已有管理员,并且仅在没有管理员时进行设置。否则,每次添加成员时,您都会将第一个成员设置为admin。但这可能是你想要的。

UI / UX明智地我不希望随机成员成为管理员,而是团队创建者在创建团队时必须立即指派团队管理员。

[更新2] 您在set_admin的关联members上定义了team方法,但是您没有使用该关系来构建成员,所以永远不会触发该方法。 您可以通过添加日志方法轻松验证这一点。

您创建了一个拥有新团队的用户,因此您可以在teams关联上添加方法。但这对我来说似乎有点多余:你知道你要添加哪个团队,以及哪个用户。

在你的控制器中,你会有类似的东西(只是猜测)

user.save

将创建用户和嵌套团队,并根据定义,创建其间的成员。我会采取明确的方法。

选项1:保存后,添加此行

user.members.last.update_attributes admin: true

因为最后添加的成员关系是刚刚创建的成员关系。这感觉有点脏。

选项2:保存后,添加此行

user.teams.last.set_admin

这看起来更好一些。因此,您可以删除after_add: :set_admin选项,因为在创建时正确设置了admin标志,并且在添加新成员时不需要。