如何在rails

时间:2015-12-17 19:13:54

标签: ruby-on-rails

我有一个简单的关系

class School < ActiveRecord::Base
  has_and_belongs_to_many :users
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :schools
end

用户可以成为许多学校的一部分,但同时用户可能是许多学校的管理员。我建立了一个多对多的关系来代表这个但是我不确定如何区分管理员和简单用户。

我最初想过设置一个有一个school_id和一个user_id的表,每个条目都代表学校的学校ID和学校的管理员的用户ID,但是我不知道如何用rails或者代表这个如果这是解决这个问题的最佳方法?如果是,如何在没有与之关联的模型的情况下访问该表?

我的意思是上面所说的:

school_id user_id
    1       3
    1       4

这意味着身份1的学校有2个管理员(3和4)

2 个答案:

答案 0 :(得分:3)

您正在寻找的是学校和用户之间关于has_many :through的更复杂的多重关系。此关系允许您与表示关系的表的访问权限具有多对多关系。如果您使用该关系,您的模型应如下所示:

class User < ActiveRecord::Base
  has_many :school_roles
  has_many :schools, through: :school_roles
end

class SchoolRole < ActiveRecord::Base
  belongs_to :school
  belongs_to :user
end

class School < ActiveRecord::Base
  has_many :school_roles
  has_many :users, through: :school_roles
end

这些表的迁移看起来像这样:

class CreateSchoolRoles < ActiveRecord::Migration
  def change
    create_table :schools do |t|
      t.string :name
      t.timestamps null: false
    end

    create_table :users do |t|
      t.string :name
      t.timestamps null: false
    end

    create_table :school_roles do |t|
      t.belongs_to :school, index: true
      t.belongs_to :user, index: true
      t.string :role
      t.timestamps null: false
    end
  end
end

我建议做出#34;角色&#34; &#34; school_roles&#34;中的字段迁移一个整数,然后在模型中使用enum,如下所示:

class SchoolRole < ActiveRecord::Base
  belongs_to :school
  belongs_to :user

  enum role: [ :admin, :user ]
end

允许您以后添加更多角色,但这是您的通话

答案 1 :(得分:0)

在我看来,将多态关联与has_many :through结合起来是最好的选择。

我们假设你创建了支持模型SchoolRole,其中

 belongs_to :user
 belongs_to :school
 belongs_to :rolable, polymorphic:true

这样:

    class School ...

    has_many :administrators, :as => :schoolroles
    has_many :users, :through => :administators



@school.administrators= [..., ...]

非常敏捷。

@user=@school.administrators.build()



  class User
    has_many :roles, :as => :rolable
    def admin?
    admin=false
    self.roles.each do |r|
    if r.role_type == "administator"
    admin=true 
    break
    end
    end
   admin
    end
....