2013-08-21 9 views
5

アクティブレコードストアでは、単一のセル内でパラメータをシリアル化できます。ダイナミックアクティブレコードユーザーフォームに基づいてアクセサを格納しますか?

I.e.

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%がスキーマであるため、これは私のアプリケーションのための素晴らしい作品-less(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 > 

今、唯一の問題は、私はカスタムフォームに新しいフィールドを作成するたびに、私はそう、私はエラーが不足している方法を取得し、アクティブレコードストアアクセサにそのパラメータを追加することが必要であることです。スキーマレスフィールドに必要なViewフォームを作成し、モデル内のアクセサを決して更新することはできません。

私の質問は、ユーザーがサブフィールドを「some_random_option1221」、「another_option_here」と入力した場合に、アクセサの配列にすべてのユーザーがサブミットしたカスタムフィールドを動的に追加するかどうかです。アクセサの配列を追加し、そのフィールドを追加しますか?

ありがとうございます!リンク以下

答えて

11

。それはレールの3つの店のメソッドも使用することができるいくつかのマイナーな微調整のように見えます。

特定のモデルインスタンスが所有するストアハッシュの各フィールドキーに対して、store_accessorを動的に呼び出します。 hstore型のoptionsという名前の列を持つUserモデルがある場合、既にオプションのハッシュにアクセスできます。 (レール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 

そして各ユーザーインスタンスは、各ユーザがそのユーザのDB行のオプション欄にあるものフィールドに応じて異なるstore_accessor方法を有することができます。

コントローラでは、オプションの追加/削除/編集のための優先ユーザーインターフェイスに応じて、ユーザーにオプションをビルドして新規作成、更新、更新などからヘルパメソッドを呼び出すことができます。

レール3では、store_accessorを呼び出すのではなく、attr_accessorを呼び出すことになります。

Userクラスオブジェクトにはアクセサメソッドがないため(各ユーザーインスタンスが異なる属性を持つ可能性があるため)、User.new(:option_1 => 'some_option_value')を呼び出すことはできません。

+0

だから、 '' num_fields = options.try(:keys).try(:count)のように見えます。オプションフィールドにデフォルト値 '' {} ''を追加できるので、options.keysは空の配列になります。 – zw963

関連する問題