Dynamic Active Record Store accessors based off a user form?

后端 未结 2 504
轮回少年
轮回少年 2021-01-01 00:19

Active Record Store allows you to serialize parameters inside a single cell.

I.e.

class User < ActiveRecord::Base
  store :options, accessors: [ :         


        
相关标签:
2条回答
  • 2021-01-01 01:10

    With rails 4 and postgresql the following works for me. It looks like with some minor tweaking the rails 3 store methods could also be used.

    Call store_accessor dynamically on each of the field keys in the store hash owned by a given model instance. If you have a User model with a column named options of type hstore, then you can already access the options hash. (In rails 3, you would call the store method as in the code in your question to make the options method work.)

    Create a method to do this whenever your user interface adds a new field. Then also call this method after_initialize so loading a user from the db will set up the field name accessors at load time. You might also want to call this method 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
    

    Then each user instance can have different store_accessor methods depending on what fields each user has in the options column in the db row for that user.

    In your controller, depending on your preferred user interface for adding/removing/editing the options, you can have a helper method to build the options on a user, and call it from new, create, update, etc.

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

    In rails 3, rather than calling store_accessor, you would be calling attr_accessor.

    Note that you won't be able to call User.new(:option_1=>'some_option_value') because the User class object doesn't have the accessor methods (since each user instance could have different attributes.)

    0 讨论(0)
  • 2021-01-01 01:22

    Check out following links: https://www.ruby-forum.com/topic/113069

    How do I set an attr_accessor for a dynamic instance variable?

    0 讨论(0)
提交回复
热议问题