导轨的has_many:通过,空belongs_to的,多belongs_to的和删除belongs_to的呢? [英] Rails has_many :through, null belongs_to, multiple belongs_to and deletion of belongs_to?

查看:140
本文介绍了导轨的has_many:通过,空belongs_to的,多belongs_to的和删除belongs_to的呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如果我在正确的轨道,如果轨道允许这样的事情。

用户有一个网​​络角色。即吉姆是历史教师在学校。

A 角色既有地位(权力)和一个名称(标签)。 吉姆是历史教师(标签),但有一个成员或管理,或监督,或任何(功率)的权威。

根据所角色 A 用户可以看到所有的活动网​​络不论他/她创造了他们。即吉姆可以看到南希,休会计划,如果吉姆是校长(管理),但如果吉姆是历史教师(成员)。

A 用户创建一个事件角色一个网​​络中。即吉姆在创建课程计划为历史教师,学校。

事件永远连接到特定的网​​络,目前该角色

我要那个事件来坚持,如果用户替换另一个用户角色,以及新的用户可以访问事件。例如汤姆取代吉姆,成为历史教师,可以修改教案,因为他是历史教师。 吉姆将不再能访问课程计划。

不过,我也希望有一个事件来坚持,如果没有用户附属于角色。例如汤姆被解雇,并且没有电流替代,管理员仍然可以看到课程计划。

最后,如果角色被删除,事件仍然存在,如连接到网络没有角色

该型号的下方,我使用惨惨的授权,而这些是我的问题:

  1. 可以一个角色缺少的一个用户,或者我需要创建一些通用的无用户或每个人用户?并能事件缺少的一个角色? (可belongs_to的为空?)
  2. 这是好/坏的设计来连接事件来既角色网络?有没有更好的方式来做到这一点?
  3. 如果一个用户可以看到更多的事件,这取决于他/她的角色他们有很多活动通过网​​络或它们的角色?我通过网​​络和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:

  1. Can a role be missing a User, or would I need to create some generic "None" User or "Everyone" User? And can Event be missing a Role? (Can belongs_to be null?)
  2. Is it good/bad design to connect an Event to both a Role and a Network? Is there a better way to do this?
  3. If a User can see more events depending on his/her Role do they have many Events through the Network or their Role? I am thinking through Network 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆