在我们的Rails 4应用程序中,有四种模式:
class User < ActiveRecord::Base
has_many :administrations, dependent: :destroy
has_many :calendars, through: :administrations
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
class Calendar < ActiveRecord::Base
has_many :administrations, dependent: :destroy
has_many :users, through: :administrations
has_many :posts, dependent: :destroy
end
class Post < ActiveRecord::Base
belongs_to :calendar
end
以下是相应的迁移:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :first_name
t.string :last_name
t.string :email
t.integer :total_calendar_count
t.integer :owned_calendar_count
t.timestamps null: false
end
end
end
class CreateAdministrations < ActiveRecord::Migration
def change
create_table :administrations do |t|
t.references :user, index: true, foreign_key: true
t.references :calendar, index: true, foreign_key: true
t.string :role
t.timestamps null: false
end
end
end
class CreateCalendars < ActiveRecord::Migration
def change
create_table :calendars do |t|
t.string :name
t.timestamps null: false
end
end
end
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.references :calendar, index: true, foreign_key: true
t.date :date
t.time :time
t.string :focus
t.string :format
t.string :blog_title
t.text :long_copy
t.text :short_copy
t.string :link
t.string :hashtag
t.string :media
t.float :promotion
t.string :target
t.integer :approval
t.text :comment
t.timestamps null: false
end
end
end
基本上,user
可以包含多个calendar
,calendar
可以包含多个user
。
当@user
创建新的@calendar
时,我们会生成新的@administration
:目前正在使用此功能。
我们现在要做的是允许@user
邀请已注册或未注册的其他@user
加入现有@calendar
。
这会在受邀@administration
和现有@user
之间创建新的@calendar
。
这里棘手的部分 - 或者至少是我们的模糊部分 - 似乎是处理已注册和未注册的用户:
对于未注册的用户:当“邀请”user
与“邀请”calendar
共享user
时,我们如何允许后者通过电子邮件地址由前者输入,同时允许他通过他选择的电子邮件地址(相同或另一个)注册到应用程序?
对于注册用户:当“邀请”user
与“邀请”calendar
共享user
时,我们如何允许后者通过电子邮件地址由前者输入,同时允许他使用现有帐户登录应用程序(与“邀请”user
使用的电子邮件地址相同或不同的电子邮件地址)或注册他选择的电子邮件地址(“邀请”user
或其他地址使用的电子邮件地址)?
最重要的是,我们如何保留与calendar
相关的信息(比方说calendar_id
),以便“受邀”user
登录或注册后,他有权访问calendar
“邀请”用户想要授予他访问权限吗?
注意:我们目前正在使用Michael Hartl's Rails Tutorial中建议的自定义身份验证/授权系统,并且未使用Devise
或其他gem。
现在,问题是如何实现这一目标:
invite
模型中创建Administration
方法并在AdministrationsController#new
中使用它?InvitationsController
吗?答案 0 :(得分:1)
好的,这是我的2美分。如果您需要更多信息,请与我们联系。
因为您已经进行了自定义身份验证和授权,所以此解决方案可能会对您有所帮助。
我认为您的访问列表应该是这样的,因为我在发布的迁移中看不到您的访问列表。
无论如何,在注册时,您需要为每个用户分配一个令牌。
这样的事情:
before_create :generate_token
private
def generate_token
begin
self.a_token = SecureRandom.hex
end while self.class.exists?(a_token: access_token)
end
然后,当用户邀请时,只需分配此令牌即可。
现在,您需要在注册时使用方法来识别令牌,然后填写Invite表。
休息应该很容易。在身份验证模块中,只需使用以下方法:
def invited_by
Invite.where(:user_id => current_user.id).first
end
(我不喜欢你可以使用的find_by_
方法find_by_user_id
- 我有点老式;)
(我假设您制作了一个模块,您可以在整个应用程序中使用它)如果没有,请告诉我,我会帮助您完成配对。
所以现在你有了邀请你当前用户的用户。现在,只需返回您为当前用户邀请的用户分配的权限,然后继续使用该应用程序。
希望它有所帮助。如果您需要更多指导,请告诉我。我使用相同的方法进行联盟计划申请和成为联盟会员的会员福利。
干杯。
<强>更新强>
因为您询问了授权模块并且您有自定义身份验证。这里有一些代码。 (部分测试和需要重构请使用它作为指导,它们是我能想到的一些常见任务)
module AuthorisationRelated
def what_are_current_user_roles
objArray = []
current_user.roles.each do |role|
objArray.push role.name
end
return objArray
end
def does_user_have_this_role?(role_name)
result = false
obj_array = what_are_current_user_roles
obj_array.each do |a_role|
if a_role == role_name
result = true
end
end
result
end
def is_admin?
athu = false
if signed_in?
current_user.roles.each do |role|
if role.name == 'admin'
athu = true
end
end
end
return athu
end
# class_instance MUST be a parent class
# If you need to Authenticate Model then your class_instance has to be @instance
def user_allowed_create_and_edit?(class_model, class_instance)
user_is_allowed = false
if permitted_to? :create, class_model.new and has_user_own_this(class_instance)
user_is_allowed = true
else
user_is_allowed = false
end
# Override everything if user is admin
if is_admin?
user_is_allowed = true
end
return user_is_allowed
end
# relation has to be set to access_list
def has_user_own_this(model)
user_who_owns_this = model.access_list.user_id
if current_user.id == user_who_owns_this
return true
else
return false
end
end
def find_current_user_acls
acl = []
acls = AccessList.joins(:user).where("users.id = ?",current_user.id)
acls.each do |an_acl|
acl.push an_acl.id
end
acl
end
end
<强>更新强>
根据您对授权的良好来源发表评论。 我建议使用Gems或至少一个可以处理复杂任务的Authorization Gem。
我的所有时间爱人之一Declarative Authorization。我已经在具有6个不同组ACL的网站上实现了与此Gem相同的数据库结构,以及超过500K活跃用户的存储桶权限。
查看本教程:http://railscasts.com/episodes/188-declarative-authorization非常好的起点。
因为您没有Devise或类似的东西,所以请确保您拥有current_user
便利。您可以在ApplicationController
本教程将告诉您如何制作当前用户(付费教程 - 值得 - 相信我!)http://railscasts.com/episodes/250-authentication-from-scratch-revised