ruby-on-rails – 基于用户表单的Dynamic Active Record Store访问器?

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 基于用户表单的Dynamic Active Record Store访问器?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
Active Record Store允许您序列化单个单元格内的参数.

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

所有访问器现在都在users表的“options”列中序列化.

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访问器,否则我会得到一个方法缺失错误.如果我可以进入并为无模式字段创建尽可能多的View表单并且永远不更新模型中的访问器,那将是很好的.

所以我的问题是:是否有动态添加所有用户提交的自定义字段到访问者数组,这样如果用户提交字段“some_random_option1221”,“another_option_here”然后我不必进入访问者数组并添加那个领域?

谢谢!

解决方法

使用rails 4和postgresql以下内容适用于我.通过一些小的调整看起来也可以使用rails 3存储方法.

在给定模型实例拥有的商店哈希中的每个字段键上动态调用store_accessor.如果您的用户模型具有名为hstore类型的选项的列,则您可以访问选项哈希. (在rails 3中,您可以像在问题中的代码中一样调用store方法,以使选项方法有效.)

只要您的用户界面添加新字段,就创建一个方法来执行此操作.然后还调用方法after_initialize,以便从db加载用户将在加载时设置字段名称访问器.您可能还想调用方法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行的options列中具有的字段.

在您的控制器中,根据您添加/删除/编辑选项的首选用户界面,您可以使用帮助程序方法用户上构建选项,并从新建,创建,更新等中调用它.

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类对象没有访问器方法(因为每个用户实例可能具有不同的属性.)

猜你在找的Ruby相关文章