Ruby on rails 对于其他用户来说,将概要文件模型的某些属性设置为公共(可见)或私有(不可见)的最佳方法是什么?
我有一个个人资料模型,它有许多属性,如电子邮件,图像,年龄,地址等。 最终用户可以将某些属性设置为私有,以便其他用户无法查看这些属性。 我通过向表Ruby on rails 对于其他用户来说,将概要文件模型的某些属性设置为公共(可见)或私有(不可见)的最佳方法是什么?,ruby-on-rails,ruby,activerecord,serialization,Ruby On Rails,Ruby,Activerecord,Serialization,我有一个个人资料模型,它有许多属性,如电子邮件,图像,年龄,地址等。 最终用户可以将某些属性设置为私有,以便其他用户无法查看这些属性。 我通过向表private\u attr中添加一列并将其序列化以存储如下哈希值来解决此问题:- {email: true, address: true, age: false } 在这里,作为具有值true的键的属性被认为是私有的,并且除了这些属性所属的用户之外,不会显示给其他用户 我想知道这是解决这个问题的最好办法,还是有其他办法。 提前谢谢 你问是否还有其他
private\u attr
中添加一列并将其序列化以存储如下哈希值来解决此问题:-
{email: true, address: true, age: false }
在这里,作为具有值true
的键的属性被认为是私有的,并且除了这些属性所属的用户之外,不会显示给其他用户
我想知道这是解决这个问题的最好办法,还是有其他办法。
提前谢谢 你问是否还有其他方法。当然一个是否更好取决于你 很多列 可以为每个属性创建其他列。受保护的电子邮件:真/假(等)。如果您只有3列,这还不算太糟,但如果您要保护很多属性,则无法很好地扩展 多对多关系 您可以使用其他模型,例如ProtectedAttribute。配置文件具有许多受保护的属性,并将数据存储在单独的表中,而不是序列化。这会将序列化数据消除到单个列中 其他详细信息如下所示
# I'm using User instead of Profile as Profile is a protected word in Rails
class User < ActiveRecord::Base
has_many :profile_protected_attributes
has_many :protected_attributes, through: :profile_protected_attributes
def protect_attribute?(name)
protected_attributes.where(name: name).present?
end
def show_attribute?(name)
!protect_attribute(name)
end
def protect_attribute(name)
return if self.protect_attribute?(name)
protected_attributes << ProtectedAttribute.find_by_name(name)
end
def unprotect_attribute(name)
protected_attributes.delete(ProtectedAttribute.find_by_name(name))
end
end
class ProtectedAttribute < ActiveRecord::Base
has_many :profile_protected_attributes
has_many :users, through: :profile_protected_attributes
end
# The join model
class ProfileProtectedAttribute < ActiveRecord::Base
belongs_to :user
belongs_to :protected_attribute
end
#我使用的是User而不是Profile,因为Profile在Rails中是一个受保护的字
类用户 受保护的属性您可以使用名为的gem来处理您在ruby文件中定义的不同类型用户的权限(ability.rb
)。然后,我建议您为一个资源使用不同的序列化程序,每个序列化程序专用于特定的用户角色,这很容易处理。我认为您可以只序列化用户希望在数组中私有的字段(而不是散列)。比如[:email,:address]
(使用您的示例)
然后,在渲染视图时,只需检查该列中是否存在该字段。差不多
<%= user.email unless user.private_fields.include?(:email) %>
事实上,如果我必须处理8到10个属性,我会这么做。但是,如果您的Profile
模型类的属性太多,并且在用户组、公共、共享等基础上显示这些属性的逻辑很复杂,那么我建议您将其移动到单独的模型类,比如:“ProfileConfiguration
或ProfileSetting
”,它将在行级别上维护每个属性,或者您可以将这些设置移动到Redis,其中的结构如下:user\u id:{attribute\u name:true,type:'type\u name'}
,但有一个缺点是您将取决于Redis服务器的可用性
现在,就你而言:
serialize :profile_preferences, Hash
然后你用(正如你提到的,与他们的任务相反的方式)来维护它:
但是,您可以继续创建一些方便的方法,您可以在您的profile对象上调用这些方法:
after_initialize :load_profile_preferences
private
def load_profile_preferences
profile_preferences.each do |attr, value|
self.class.send(:define_method, "show_#{attr.to_s}?") { value }
end
end
现在,您可以在Profile
类的对象上获得方便的方法,如:show\u email?
,show\u address?
,以及show\u age?
,您可以将这些方法添加到User
类实例。因此,您现在可以在视图中执行类似操作,例如:
<%= "Email: {user.email}" if user.show_email? %>
<%= "Address: {user.address}" if user.show_address? %>
<%= "Age: {user.age}" if user.show_age? %>
谢谢,我有兴趣了解更多关于第一种方法的信息,即使用配置文件配置
模型,您能否详细介绍一下,如何使用它管理多个用户属性。当然,我很乐意详细介绍一下,请给我一些时间。您能解释一下使用ProtectedAttribute
model的可能解决方案吗?当然。当我有时间写详细信息时,我会更新我的答案。我已经用类关系和一些示例帮助器方法更新了我的答案。结合Presenter模式(视图上实例化的类,有关于如何显示属性的方法等),在我看来,这将是最好的方式+1@MrYoshiji然后请添加您的答案。@SachinSingh将show\u if\u allowed方法放在助手中,而不是放在演示者中,如下所示
serialize :profile_preferences, Hash
{email: false, address: false, age: true }
after_initialize :load_profile_preferences
private
def load_profile_preferences
profile_preferences.each do |attr, value|
self.class.send(:define_method, "show_#{attr.to_s}?") { value }
end
end
<%= "Email: {user.email}" if user.show_email? %>
<%= "Address: {user.address}" if user.show_address? %>
<%= "Age: {user.age}" if user.show_age? %>