Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/52.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 对于其他用户来说,将概要文件模型的某些属性设置为公共(可见)或私有(不可见)的最佳方法是什么?_Ruby On Rails_Ruby_Activerecord_Serialization - Fatal编程技术网

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? %>