模型的has_many用户(一个特定的角色类型) [英] model has_many users(of a specific role type)
问题描述
我有一个pretty的标准色器件的用户模型模式与角色,是一个多对多的模式userRoles:
#teacher或学生
CREATE_TABLE角色,:力=>真做| T |
t.string名
结束
CREATE_TABLEuser_roles:力=>真做| T |
t.integerUSER_ID
t.integerROLE_ID
结束
add_indexuser_roles,[ROLE_ID]:名称=> index_user_roles_on_role_id
add_indexuser_roles,[user_ID的]:名称=> index_user_roles_on_user_id
CREATE_TABLE用户,:力=>真做| T |
t.string电子邮件,:默认=> :空=>假
t.stringencrypted_password:默认=> :空=>假
........更多的东西....
结束
add_index用户,[电子邮件]:名称=> index_users_on_email:独特=>真正
add_index用户,[reset_password_token]:名称=> index_users_on_reset_password_token:独特=>真正
结束
该角色是教师和学生。我想创建一个 clazz所
(如学校班级)模型多对多的学生(用户与学生的角色)和多对多的老师(用户与教师的角色)
我认为这将是这个样子,但不能完全得到它:
轨道摹支架clazz所名称:字符串时间:日期时间的has_many:用户的has_many(类学生):用户(型教师)
我该怎么办的最后两?难道我创建的has_many,:通过关联迁移(teacherClass和studentClass)第一?或者是有一个辅助的方法?
也许我只是找不到合适的教程或例子,所以我可以提前使用的这些以及...感谢一个
这是我的尝试@Cody Caughlan的答案
了解更多信息Schema.rb:
的ActiveRecord :: Schema.define(:版本=> 20130523111519)办
CREATE_TABLEclass_instructions:力=>真做| T |
t.string名
t.datetime时间
t.integerUSER_ID
t.datetimecreated_at:空=>假
t.datetime的updated_at:空=>假
结束
add_indexclass_instructions,[user_ID的]:名称=> index_class_instructions_on_user_id
CREATE_TABLE角色,:力=>真做| T |
t.string名
t.datetimecreated_at:空=>假
t.datetime的updated_at:空=>假
结束
CREATE_TABLE歌曲,:力=>真做| T |
t.string称号
t.string内容
t.datetimecreated_at:空=>假
t.datetime的updated_at:空=>假
t.integerUSER_ID
t.stringfractionRe presentation
t.stringmeasureRe presentation
结束
CREATE_TABLEuser_roles:力=>真做| T |
t.integerUSER_ID
t.integerROLE_ID
t.datetimecreated_at:空=>假
t.datetime的updated_at:空=>假
结束
add_indexuser_roles,[ROLE_ID]:名称=> index_user_roles_on_role_id
add_indexuser_roles,[user_ID的]:名称=> index_user_roles_on_user_id
CREATE_TABLE用户,:力=>真做| T |
t.string电子邮件,:默认=> :空=>假
t.stringencrypted_password:默认=> :空=>假
t.stringreset_password_token
t.datetimereset_password_sent_at
t.datetimeremember_created_at
t.integersign_in_count:默认=> 0
t.datetimecurrent_sign_in_at
t.datetimelast_sign_in_at
t.stringcurrent_sign_in_ip
t.stringlast_sign_in_ip
结束
add_index用户,[电子邮件]:名称=> index_users_on_email:独特=>真正
add_index用户,[reset_password_token]:名称=> index_users_on_reset_password_token:独特=>真正
结束
User.rb模式:
类用户的LT;的ActiveRecord :: Base的
#DEVISE STUFF
#==协会
的has_many:user_roles,:依赖=> :破坏
的has_many:角色:通过=> :user_roles
的has_many:歌曲
#==实例方法
高清thisUsersID
self.id
结束
高清student_classes(class_instruction_name)
member_classes(class_instruction_name,学生)
结束
高清teacher_classes(class_instruction_name)
member_classes(class_instruction_name,角色::教师)
结束
私人
高清member_classes(class_instruction_name,类型)
ClassInstruction \
.joins(:USER_ROLE)\
。凡([user_role.user_id =?,ID])\
.joins(INNER JOIN ON roles.id = user_roles.role_id角色)\
。凡(roles.name =?,类型)\
。凡(class_instruction.name =?,class_instruction_name)
结束
结束
user_role.rb模式:
类UserRole<的ActiveRecord :: Base的
belongs_to的:用户
belongs_to的:角色
的has_many:class_instructions,:依赖=> :破坏
结束
role.rb模型
类角色<的ActiveRecord :: Base的
的has_many:user_roles,:依赖=> :破坏
结束
class_instruction.rb模型(名字是'SS'and'math-101')
类ClassInstruction<的ActiveRecord :: Base的
belongs_to的:USER_ROLE
结束
错误堆栈
加载开发环境(Rails的3.2.2)
1.9.3-429页:001〕 U = User.find(3)
用户负载(的3.2ms)选择用户。*从用户WHERE用户,ID=? LIMIT 1 [身份证,3]
=> #<使用者ID:3,电子邮件:stu@test.org,encrypted_password:$ 2A $ 10 $ 2DxWWV34BRFJoLboYyWCIeXEtCPYOSe8JqpTmFU6W2i1 ......,reset_password_token:无,reset_password_sent_at:无,remember_created_at:无,sign_in_count:0,current_sign_in_at:无,last_sign_in_at:无,current_sign_in_ip:无,last_sign_in_ip:无>
1.9.3-429页:002> U.student_classes(数学-101)。全部
ClassInstruction负荷(为0.2ms)选择class_instructions。* FROMclass_instructionsINNER JOINuser_rolesONuser_roles。ID=class_instructions。user_role_idINNER JOIN ON roles.id = user_roles.role_id WHERE角色( user_role.user_id = 3)和(roles.name ='学生')和(class_instruction.name ='数学-101)
:: sqlite3的的SQLException:没有这样的列:user_role.user_id:选择class_instructions*从角色class_instructionsINNER JOINuser_rolesONuser_roles,ID=class_instructionsuser_role_idINNER JOIN角色。 ID = user_roles.role_id WHERE(user_role.user_id = 3)和(roles.name ='学生')和(class_instruction.name ='数学-101)
ActiveRecord的:: StatementInvalid:SQLite3的::的SQLException:没有这样的列:user_role.user_id:。选择class_instructions* FROMclass_instructionsINNER JOINuser_rolesONuser_roles,ID=class_instructionsuser_role_id作者:参加关于roles.id = user_roles.role_id角色WHERE(user_role.user_id = 3)和(roles.name ='学生')和(class_instruction.name ='数学-101)
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/sqlite3-1.3.7/lib/sqlite3/database.rb:91:in'初始化'
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/sqlite3-1.3.7/lib/sqlite3/database.rb:91:in'新'
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/sqlite3-1.3.7/lib/sqlite3/database.rb:91:in`prepare
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/connection_adapters/sqlite_adapter.rb:246:in `块exec_query
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract_adapter.rb:280:in `块日志
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activesupport-3.2.2/lib/active_support/notifications/instrumenter.rb:20:in `仪器
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract_adapter.rb:275:in '登录'
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/connection_adapters/sqlite_adapter.rb:242:in `exec_query
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/connection_adapters/sqlite_adapter.rb:460:in '选择'
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract/database_statements.rb:18:in `SELECT_ALL
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract/query_cache.rb:63:in `SELECT_ALL
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/querying.rb:38:in `块的find_by_sql
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/explain.rb:40:in`logging_query_plan
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/querying.rb:37:in `的find_by_sql
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/relation.rb:171:in `exec_queries
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/relation.rb:160:in `块to_a
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/explain.rb:33:in`logging_query_plan
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/relation.rb:159:in `to_a
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/relation/finder_methods.rb:159:in '所有'
从(IRB):2
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/railties-3.2.2/lib/rails/commands/console.rb:47:in'开始'
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/railties-3.2.2/lib/rails/commands/console.rb:8:in'开始'
从/Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/railties-3.2.2/lib/rails/commands.rb:41:in`<顶(必填)>
从脚本/导轨:6:在'要求'
从脚本/导轨:6:`<主>1.9.3-429页:003>
首先,类
是一个保留字在Ruby中,所以你将不能够使用它作为一个型号名称。
http://www.java2s.com/code /红宝石/语言-基础/ Rubysreservedwords.htm
所以,选择一个不同的名称。在这样的我都做的情况下 clazz所
。
对于数据模型 - 是的,你会在指定的ActiveRecord类的定义,而不是在迁移的关系
它不清楚你的 clazz所
模型的样子。但我会假设它有2列:名称
和 user_role_id
。你可能要拔出名称到一个单独的表,并将它换成像 clazz_id
- 。但现在,我们将保持平坦
我会用一个实例方法建立关联,但你也许能够得到疯狂的的has_many
定义。
clazz类<的ActiveRecord :: Base的
belongs_to的:USER_ROLE
结束
类用户
#==协会
的has_many:user_roles,:依赖=> :破坏
的has_many:角色:通过=> :user_roles
#==实例方法
高清student_classes(clazz_name)
member_classes(clazz_name,角色::学生)
结束
高清teacher_classes(clazz_name)
member_classes(clazz_name,角色::教师)
结束
私人
高清member_classes(clazz_name,类型)
clazz所\
.joins(:USER_ROLE)\
。凡([user_role.user_id =?,ID])\
.joins(INNER JOIN ON roles.id = user_roles.role_id角色)\
。凡(roles.name =?,类型)\
。凡(clazzes.name =?,clazz_name)
结束
结束
类UserRole
的has_many:clazzes,:依赖=> :破坏
结束
类角色
的has_many:user_roles,:依赖=> :破坏
结束
因此,这将让你做这样的事情:
用户= User.find(99)#我们知道这个用户是学生
user.student_classes(社会科学101)所有。
类似的东西。
I have a pretty standard devise user model schema with roles and a many to many model for userRoles:
#teacher or student
create_table "roles", :force => true do |t|
t.string "name"
end
create_table "user_roles", :force => true do |t|
t.integer "user_id"
t.integer "role_id"
end
add_index "user_roles", ["role_id"], :name => "index_user_roles_on_role_id"
add_index "user_roles", ["user_id"], :name => "index_user_roles_on_user_id"
create_table "users", :force => true do |t|
t.string "email", :default => "", :null => false
t.string "encrypted_password", :default => "", :null => false
........more stuff....
end
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true
end
The roles are teacher and student. I want to create a Clazz
(as in school class) model with many to many students (users with role of students) and many to many teachers (users with role of teachers).
I think it would look something like this, but can't quite get it:
rails g scaffold Clazz name:string time:datetime has_many:users(of type student) has_many:users(of type teacher)
How do I do the last two? Do I create the has_many, :through association migrations (teacherClass and studentClass) first? or is there a helper method?
Maybe I just couldn't find an appropriate tutorial or example, so i could use one of those as well... Thanks in advance
This is more information about my attempt at @Cody Caughlan 's answer
Schema.rb :
ActiveRecord::Schema.define(:version => 20130523111519) do
create_table "class_instructions", :force => true do |t|
t.string "name"
t.datetime "time"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "class_instructions", ["user_id"], :name => "index_class_instructions_on_user_id"
create_table "roles", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "songs", :force => true do |t|
t.string "title"
t.string "content"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "user_id"
t.string "fractionRepresentation"
t.string "measureRepresentation"
end
create_table "user_roles", :force => true do |t|
t.integer "user_id"
t.integer "role_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "user_roles", ["role_id"], :name => "index_user_roles_on_role_id"
add_index "user_roles", ["user_id"], :name => "index_user_roles_on_user_id"
create_table "users", :force => true do |t|
t.string "email", :default => "", :null => false
t.string "encrypted_password", :default => "", :null => false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", :default => 0
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
end
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true
end
User.rb model :
class User < ActiveRecord::Base
#DEVISE STUFF
#== Associations
has_many :user_roles, :dependent => :destroy
has_many :roles, :through => :user_roles
has_many :songs
#== Instance Methods
def thisUsersID
self.id
end
def student_classes(class_instruction_name)
member_classes(class_instruction_name, 'Student')
end
def teacher_classes(class_instruction_name)
member_classes(class_instruction_name, Role::TEACHER)
end
private
def member_classes(class_instruction_name, type)
ClassInstruction \
.joins(:user_role) \
.where(["user_role.user_id = ?", id]) \
.joins("INNER JOIN roles ON roles.id = user_roles.role_id") \
.where("roles.name = ?", type) \
.where("class_instruction.name = ?", class_instruction_name)
end
end
user_role.rb model:
class UserRole < ActiveRecord::Base
belongs_to :user
belongs_to :role
has_many :class_instructions, :dependent => :destroy
end
role.rb model
class Role < ActiveRecord::Base
has_many :user_roles, :dependent => :destroy
end
class_instruction.rb model (names are 'ss' and'math-101')
class ClassInstruction < ActiveRecord::Base
belongs_to :user_role
end
Error Stack
Loading development environment (Rails 3.2.2)
1.9.3-p429 :001 > U = User.find(3)
User Load (3.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 3]]
=> #<User id: 3, email: "stu@test.org", encrypted_password: "$2a$10$2DxWWV34BRFJoLboYyWCIeXEtCPYOSe8JqpTmFU6W2i1...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil>
1.9.3-p429 :002 > U.student_classes('math-101').all
ClassInstruction Load (0.2ms) SELECT "class_instructions".* FROM "class_instructions" INNER JOIN "user_roles" ON "user_roles"."id" = "class_instructions"."user_role_id" INNER JOIN roles ON roles.id = user_roles.role_id WHERE (user_role.user_id = 3) AND (roles.name = 'Student') AND (class_instruction.name = 'math-101')
SQLite3::SQLException: no such column: user_role.user_id: SELECT "class_instructions".* FROM "class_instructions" INNER JOIN "user_roles" ON "user_roles"."id" = "class_instructions"."user_role_id" INNER JOIN roles ON roles.id = user_roles.role_id WHERE (user_role.user_id = 3) AND (roles.name = 'Student') AND (class_instruction.name = 'math-101')
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: user_role.user_id: SELECT "class_instructions".* FROM "class_instructions" INNER JOIN "user_roles" ON "user_roles"."id" = "class_instructions"."user_role_id" INNER JOIN roles ON roles.id = user_roles.role_id WHERE (user_role.user_id = 3) AND (roles.name = 'Student') AND (class_instruction.name = 'math-101')
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/sqlite3-1.3.7/lib/sqlite3/database.rb:91:in `initialize'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/sqlite3-1.3.7/lib/sqlite3/database.rb:91:in `new'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/sqlite3-1.3.7/lib/sqlite3/database.rb:91:in `prepare'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/connection_adapters/sqlite_adapter.rb:246:in `block in exec_query'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract_adapter.rb:280:in `block in log'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activesupport-3.2.2/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract_adapter.rb:275:in `log'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/connection_adapters/sqlite_adapter.rb:242:in `exec_query'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/connection_adapters/sqlite_adapter.rb:460:in `select'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract/database_statements.rb:18:in `select_all'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract/query_cache.rb:63:in `select_all'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/querying.rb:38:in `block in find_by_sql'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/explain.rb:40:in `logging_query_plan'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/querying.rb:37:in `find_by_sql'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/relation.rb:171:in `exec_queries'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/relation.rb:160:in `block in to_a'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/explain.rb:33:in `logging_query_plan'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/relation.rb:159:in `to_a'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/activerecord-3.2.2/lib/active_record/relation/finder_methods.rb:159:in `all'
from (irb):2
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/railties-3.2.2/lib/rails/commands/console.rb:47:in `start'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/railties-3.2.2/lib/rails/commands/console.rb:8:in `start'
from /Users/phycom06/.rvm/gems/ruby-1.9.3-p429/gems/railties-3.2.2/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'1.9.3-p429 :003 >
Firstly, Class
is a reserved word in Ruby so you will not be able to use it as a Model name.
http://www.java2s.com/Code/Ruby/Language-Basics/Rubysreservedwords.htm
So pick a different name. In cases like this I have done Clazz
.
As for the data model - yes you would specify the relationships in the ActiveRecord class definition and not in the migration.
Its not clear what your Clazz
model looks like. But I will assume it has 2 columns: name
and a user_role_id
. You'd probably want to pull out the name into a separate table and have it be replaced with like a clazz_id
- but for now we will keep it flat.
I will use an instance method to build the associations, but you might be able to get crazy in the has_many
definitions.
class Clazz < ActiveRecord::Base
belongs_to :user_role
end
class User
#== Associations
has_many :user_roles, :dependent => :destroy
has_many :roles, :through => :user_roles
#== Instance Methods
def student_classes(clazz_name)
member_classes(clazz_name, Role::STUDENT)
end
def teacher_classes(clazz_name)
member_classes(clazz_name, Role::TEACHER)
end
private
def member_classes(clazz_name, type)
Clazz \
.joins(:user_role) \
.where(["user_role.user_id = ?", id]) \
.joins("INNER JOIN roles ON roles.id = user_roles.role_id") \
.where("roles.name = ?", type) \
.where("clazzes.name = ?", clazz_name)
end
end
class UserRole
has_many :clazzes, :dependent => :destroy
end
class Role
has_many :user_roles, :dependent => :destroy
end
So this will enable you to do something like:
user = User.find(99) # we know this user is a student
user.student_classes('Social Studies 101').all
Something like that.
这篇关于模型的has_many用户(一个特定的角色类型)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!