6

Active Record Store 允许您在单个单元格内序列化参数。

IE

class User < ActiveRecord::Base
  store :options, accessors: [ :option1, :option2, :another_random_option ]
end

现在,所有访问器都在 users 表的“选项”列中序列化。

u = User.new
u.option2 = 'some option'
u.option2 # => 'some option'

这对我的应用程序非常有用,因为我必须每天创建许多表单,其中 90% 的表单是相同的(用户名、爱好、兴趣等),然后 10% 是无模式的(random_option_here、another_random_option_in_another_form) . 我也不需要按无模式选项进行排序。

我所做的是我为始终相同的 90% 的表单字段创建了 1 个表,然后我有另一个包含最后 10% 字段的表(我有另一个表的原因是因为这是一个 belongs_to 关系,因此用户可以在此表中有很多行)。

<%= form_tag do %> 
  <%= #render partial form for an object that has non-changing fields %>
  ...
  <%= #render a schema-less partial form based off an ID passed here %>
<% end >

现在唯一的问题是,每次我在自定义表单中创建一个新字段时,我都必须将该参数添加到 Active Record Store 访问器中,否则我会收到一个方法丢失错误。如果我可以进入并为无模式字段创建尽可能多的视图表单,并且永远不会更新模型中的访问器,那就太好了。

所以我的问题是:无论如何,是否可以将所有用户提交的自定义字段动态添加到访问器数组中,这样如果用户提交了字段“some_random_option1221”,“another_option_here”,那么我就不必进入访问器数组并添加那个领域?

谢谢!

4

2 回答 2

13

使用 rails 4 和 postgresql,以下对我有用。看起来通过一些小的调整也可以使用 rails 3 store 方法。

在给定模型实例拥有的存储哈希中的每个字段键上动态调用 store_accessor。如果您有一个用户模型,其中有一列名为 options 的 hstore 类型,那么您已经可以访问选项哈希。(在 rails 3 中,您可以像问题中的代码一样调用 store 方法以使 options 方法起作用。)

每当您的用户界面添加新字段时,创建一个方法来执行此操作。然后还调用此方法 after_initialize 以便从数据库加载用户将在加载时设置字段名称访问器。您可能还想在 after_save 调用此方法。

class User < ActiveRecord::Base
  after_initialize :add_field_accessors
  after_save       :add_field_accessors

  def add_store_accessor field_name
    singleton_class.class_eval {store_accessor :options, field_name}
  end

  def add_field_accessors
    num_fields = options.try(:keys).try(:count) || 0
    options.keys.each {|field_name| add_store_accessor field_name} if num_fields > 0
  end
end

然后每个用户实例可以有不同的 store_accessor 方法,具体取决于每个用户在该用户的 db 行的选项列中具有哪些字段。

在您的控制器中,根据您用于添加/删除/编辑选项的首选用户界面,您可以有一个辅助方法来为用户构建选项,并从新建、创建、更新等中调用它。

def build_options
  @user.options = options_hash
  @user.add_field_accessors
end

在 Rails 3 中,您将调用 attr_accessor,而不是调用 store_accessor。

请注意,您将无法调用 User.new(:option_1=>'some_option_value') 因为 User 类对象没有访问器方法(因为每个用户实例可能具有不同的属性。)

于 2013-09-15T18:11:29.850 回答
0

查看以下链接: https ://www.ruby-forum.com/topic/113069

如何为动态实例变量设置 attr_accessor?

于 2013-08-21T06:09:48.697 回答