0

我正在寻找一种促进用户偏好的机制。如果当前登录的用户没有特定的首选项集,我还希望使用一组“主”首选项。我看到几个与此类似的问题,但它们似乎进入了理论,而不是简单地提出一个高质量的解决方案。

基本上我正在寻找有关管理和存储的输入——模型、控制器等。最初我正​​在考虑简单地使用一个包含 50 多列的规范化表(用于性能等)。但是,我计划在未来添加各种未知的偏好,除了性能之外,我可以想象多个列会失控。想法?

4

2 回答 2

1

如果您不需要根据数据库中的个人偏好进行操作或排序,那么您可能需要使用单个位掩码(整数)列。基本上,位掩码是一组表示为二进制数的开/关开关。例如,假设我们有三个偏好:

  1. 查看订阅
  2. 查看颜色
  3. 查看全名

假设用户有 1 和 3 开启和 2 关闭。使用 1 表示开启,0 表示关闭,其位掩码为:

101

(开关开)

这被存储在数据库中,5因为1015 是二进制的。位掩码很容易存储在数据库中(使用单个整数列),并且在您知道运算符后很容易操作(用于将用户的偏好合并到站点默认值中)。Ryan Bates 有一个关于在 Rails 中使用位掩码的很棒的教程:Emmbedded Association。希望这将为您提供您正在寻找的具体示例。

于 2009-12-22T04:14:45.013 回答
0

在我看来,定义和使用默认值的最佳方法是在用户偏好表中添加另一行,并将其作为类变量加载到模型中。如果未找到首选项,则覆盖访问器以查找默认值。像这样的东西:

class UserPreference < ActiveRecord::Base
  # load default preferences as a class variable
  @@defaults ||= find(1).attributes

  # redefine accessors or each column to load default if nil
  column_names.each do |column|
    method_name = "#{column}_with_default".to_sym
    send :define_method, method_name do 
      value = send("#{column_without_default}") 
      case value
      when nil
        @@defaults[column]
      else 
        value
      end
    end
    alias_method_chain column, :default
  end
  ...
end

本质上,默认首选项(从第 1 行加载)作为类变量存储在模型中。所有访问器都被重新定义并成为别名方法链的一部分,因此如果返回值为 nil,则返回默认值。我想用 || 而不是大小写,但如果用户将布尔首选项设置为 false,则会导致问题。

编辑:注意我不知道在不重新启动服务器的情况下更新 Rails 应用程序中的默认值的好方法。

于 2009-12-22T14:46:10.630 回答