导轨的has_many:通过,空belongs_to的,多belongs_to的和删除belongs_to的呢? [英] Rails has_many :through, null belongs_to, multiple belongs_to and deletion of belongs_to?
问题描述
我想知道如果我在正确的轨道,如果轨道允许这样的事情。
用户
有一个在
。即吉姆是历史教师在学校。网络
角色
A 角色
既有地位(权力)和一个名称(标签)。 吉姆是历史教师(标签),但有一个成员或管理,或监督,或任何(功率)的权威。
根据所角色
A 用户
可以看到所有的活动
在网络
不论他/她创造了他们。即吉姆可以看到南希,休会计划,如果吉姆是校长(管理),但如果吉姆是历史教师(成员)。
A 用户
创建一个事件
为角色
一个网络中
。即吉姆在创建课程计划为历史教师,学校。
事件
永远连接到特定的网络
,目前该角色
。
我要那个事件
来坚持,如果用户
替换另一个用户
在角色
,以及新的用户
可以访问事件
。例如汤姆取代吉姆,成为历史教师,可以修改教案,因为他是历史教师。 吉姆将不再能访问课程计划。
不过,我也希望有一个事件
来坚持,如果没有用户
附属于角色
。例如汤姆被解雇,并且没有电流替代,管理员仍然可以看到课程计划。
最后,如果角色
被删除,事件
仍然存在,如连接到网络
没有角色
。
该型号的下方,我使用惨惨的授权,而这些是我的问题:
- 可以一个角色缺少的一个
用户
,或者我需要创建一些通用的无用户
或每个人用户
?并能事件
缺少的一个角色
? (可belongs_to的为空?) - 这是好/坏的设计来连接
事件
来既角色
和网络
?有没有更好的方式来做到这一点? - 如果一个
用户
可以看到更多的事件,这取决于他/她的角色
他们有很多活动
通过网络
或它们的角色
?我通过网络
和Ability.rb思考会限制它。
User.rb
类用户的LT;的ActiveRecord :: Base的
的has_many:角色
的has_many:网络:通过=> :角色
的has_many:事件:通过=> :网络
#我会用康康舞确定的授权
#什么样的网络事件,他们可以看到根据自己的角色?
结束
Network.rb
类网络12;的ActiveRecord :: Base的
的has_many:角色
的has_many:用户:通过=> :角色
的has_many:事件
#它不应该有这种通过角色吧?
#因为一个角色可以被删除
结束
Role.rb
类角色<的ActiveRecord :: Base的
belongs_to的:用户#CAN这为空?
belongs_to的:网络
结束
Event.rb
类事件<的ActiveRecord :: Base的
belongs_to的:#Can这个角色为空?
属于:网络
#它是否通过角色属于网络,
#或可以将它属于自身,万一作用被删除?
#belongs_to的:用户:通过=> :角色
#如果我使用惨惨这是必要的
#来确定用户是否能到达的事件吗?
结束
Ability.rb
如果用户
user.roles.each做|角色|
可以:管理,事件:ROLE_ID => role.id
如果role.position ==管理员|| role.position ==经理人
可以:管理,事件:NETWORK_ID => role.network_id
ELSEIF role.position ==监督员
可以:阅读,事件:NETWORK_ID => role.network_id
结束
结束
结束
您协会是很好,你可以有空 belongs_to的
字段。 Rails的默认情况下不创建数据库的外键约束。至于惨惨设置得好,我会做这样的事情:
类能力
包括惨惨::能力
高清初始化(用户)
#Adding可规则不会覆盖之前的规则,而是在逻辑或操作。
#See:https://github.com/ryanb/cancan/wiki/Ability-$p$pcedence
#Anything可以传递的条件,活动记录的哈希将在这里工作。
#系统唯一的例外正在与型号ID。
#你不能传递的模型对象直接,你必须传入的标识。
#can:管理项目,:组=> {:ID => user.group_ids}
#See https://github.com/ryanb/cancan/wiki/Defining-Abilities
能:读,事件,网络:{ID:user.supervises_network_ids}
可以:管理,事件,角色:{ID:user.role_ids}
可以:管理,事件,网络:{ID:user.manages_network_ids + user.admins_network_ids}
结束
结束
如果您有:
类用户的LT;的ActiveRecord :: Base的
#...
高清manages_network_ids
@manages_network_ids || = roles.manager.collect和放大器;:NETWORK_ID
结束
高清admins_network_ids
@admins_network_ids || = roles.admin.collect和放大器;:NETWORK_ID
结束
高清supervises_network_ids
@supervises_network_ids || = roles.supervisor.collect和放大器;:NETWORK_ID
结束
#...
结束
和对角色有:
类角色<的ActiveRecord :: Base的
#...
适用范围:经理,在那里(位置:经理人)
适用范围:admin,其中(位置:管理员)
适用范围:监事,其中(位置:主管)
#...
结束
这可以让你的事件有一个空 ROLE_ID
,因为你将允许网络上的任何管理员(或管理者)来管理所有事件,由<$ C $受限C> NETWORK_ID 。此外,如果重新分配的作用,以一个新的用户,旧的用户将不再能够管理的情况下,与新的一个意愿。
I would like to know if I am on the right track and if rails allows this sort of thing.
User
has one Role
in a Network
. i.e. "Jim" is a "History Teacher" at a "School".
A Role
has both a position (power) and a name (label). "Jim" is a "History Teacher" (label) but has the authority of a member or admin, or supervisor, or whatever (power).
Depending on that Role
a User
can see all Events
in the Network
whether or not he/she created them. i.e. "Jim" can see "Nancy's" "Recess Plan" if "Jim" is a "Principal" (admin) but not if "Jim" is a "History Teacher" (member).
A User
creates an Event
as a Role
within a Network
. i.e. "Jim" creates "Lesson Plan" as "History Teacher" at "School."
Event
is forever connected to that specific Network
and currently to that Role
.
I want that Event
to persist if a User
replaces another User
in that Role
, and the new User
can access that Event
. i.e. "Tom" replaces "Jim" as the "History Teacher" and can modify "Lesson Plan" because he is the "History Teacher". "Jim" can no longer access "Lesson Plan."
But I also want an Event
to persist if there is no User
attached to a Role
. i.e. "Tom" is fired and there is no current replacement, an admin can still see "Lesson Plan".
Finally, if that Role
is deleted, the Event
still exists as connected to that Network
without a Role
.
The models are below, I am using CanCan for authorization, and these are my questions:
- Can a role be missing a
User
, or would I need to create some generic "None"User
or "Everyone"User
? And canEvent
be missing aRole
? (Can belongs_to be null?) - Is it good/bad design to connect an
Event
to both aRole
and aNetwork
? Is there a better way to do this? - If a
User
can see more events depending on his/herRole
do they have manyEvents
through theNetwork
or theirRole
? I am thinking throughNetwork
and the Ability.rb would limit it.
User.rb
class User < ActiveRecord::Base
has_many :roles
has_many :networks, :through => :roles
has_many :events, :through => :network
# I would use CanCan to determine the authorization of
# what network events they can see based on their role?
end
Network.rb
class Network < ActiveRecord::Base
has_many :roles
has_many :users, :through => :roles
has_many :events
# it shouldn't have this through roles right?
# because a role can be deleted
end
Role.rb
class Role < ActiveRecord::Base
belongs_to :user #CAN THIS BE NULL?
belongs_to :network
end
Event.rb
class Event < ActiveRecord::Base
belongs_to :role #Can this be null?
belongs to :network
# Does it belong to the network through the role,
# or can it belong on its own, in case the role is deleted?
# belongs_to :user, :through => :roles
# Is this necessary if I am using CanCan
# to determine if a User can reach the event?
end
Ability.rb
if user
user.roles.each do |role|
can :manage, Event, :role_id => role.id
if role.position == "admin" || role.position == "manager"
can :manage, Event, :network_id => role.network_id
elseif role.position == "supervisor"
can :read, Event, :network_id => role.network_id
end
end
end
Your associations are fine, and you can have null belongs_to
fields. Rails does not create foreign-key constraints on the database by default. As far as the CanCan setup goes, I would do something like:
class Ability
include CanCan::Ability
def initialize(user)
#Adding can rules do not override prior rules, but instead are logically or'ed.
#See: https://github.com/ryanb/cancan/wiki/Ability-Precedence
#Anything that you can pass to a hash of conditions in Active Record will work here.
#The only exception is working with model ids.
#You can't pass in the model objects directly, you must pass in the ids.
#can :manage, Project, :group => { :id => user.group_ids }
#See https://github.com/ryanb/cancan/wiki/Defining-Abilities
can :read, Event, network: {id: user.supervises_network_ids}
can :manage, Event, role: {id: user.role_ids}
can :manage, Event, network: {id: user.manages_network_ids + user.admins_network_ids}
end
end
Where you have:
class User < ActiveRecord::Base
#...
def manages_network_ids
@manages_network_ids ||= roles.manager.collect &:network_id
end
def admins_network_ids
@admins_network_ids ||= roles.admin.collect &:network_id
end
def supervises_network_ids
@supervises_network_ids ||= roles.supervisor.collect &:network_id
end
#...
end
And on Role you have:
class Role < ActiveRecord::Base
#...
scope :manager, where(position: "manager")
scope :admin, where(position: "admin")
scope :supervisor, where(position: "supervisor")
#...
end
This allows your Event to have a null role_id
, since you will allow any admins (or managers) on a network to manage all events, constrained by network_id
. Also, if you reassign the role to a new user, the old user will no longer be able to manage the event, and the new one will.
这篇关于导轨的has_many:通过,空belongs_to的,多belongs_to的和删除belongs_to的呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!