Rails 3の継承データベース

実在の人々で発生した(発生している)実際のイベントに基づきます。



レガシーデータベースを使用している場合、フィールドがRuby on Railsと競合し始めたときにフィールド名を変更できない場合があります。 最も単純な例は、テーブルの1つにある「クラス」というフィールドです。 Railsは本当にこれが好きではありません。 それはあなたの新しい髪型が気に入らない義母のようなもので、彼女は可能な限りそれに注意を払っています。

劇的な才能の欠如のため、翻訳者は、プライベートではなく、共通の関連付けを作成する明るいメタファーを生成できませんでした





#      ruby-1.9.2-p0 > u = User.new :class => '1995' NoMethodError: undefined method `columns_hash' for nil:NilClass
      
      





 #   ,    ,       . ruby-1.9.2-p0 > u = User.new :name NoMethodError: undefined method `has_key?' for nil:NilClass
      
      





 #     ruby-1.9.2-p0 > u = User.new => #<User id: nil, name: nil, class: nil, created_at: nil, updated_at: nil> ruby-1.9.2-p0 > u.class = '1995' NoMethodError: undefined method `private_method_defined?' for nil:NilClass
      
      





上記の義理の母のように、髪型が修正されるまで問題は避けられません。

幸いなことに、Brian Jonesはgem safe_attributesを使用してこの問題を解決しました 。 Railsは、ActiveRecordモデルテーブルの各属性に対してプロセッサ(ゲッターとセッター)を自動的に作成します。 「クラス」などの重要なメソッドでRailsをオーバーライドしようとすると、問題が発生します。 Safe_attributesは、危険な名前を持つ属性の作成を除外します。



次のことを行うだけで十分です。

 # app/models/user.rb class User < ActiveRecord::Base bad_attribute_names :class end
      
      





gemをバンドルに追加した後、侵入者フィールド名のリストをbad_attribute_namesに渡すと、Railsがそれらのプロセッサメソッドを生成しようとすることがなくなります。 今ではすべてが動作しますが、これらのプロセッサはありません。 属性を取得/割り当ててみましょう:クラス:

 ruby-1.9.2-p0 > u = User.new => #<User id: nil, name: nil, class: nil, created_at: nil, updated_at: nil> ruby-1.9.2-p0 > u.class = '1995' => "1995" ruby-1.9.2-p0 > u => #<User id: nil, name: nil, class: "1995", created_at: nil, updated_at: nil> ruby-1.9.2-p0 > u.class => User(id: integer, name: string, class: string, created_at: datetime, updated_at: datetime)
      
      





セッターは機能し(既存の「クラス」=メソッドがなかったために作成されたと想定しています)、属性値が正しく割り当てられていることを確認できます。 しかし、デフォルトのゲッターを呼び出すと、...デフォルトの動作が発生します。



実際には、ハッシュのコンテキストで属性をいつでも使用できます(関連付けられた配列、次にハッシュ、おおよそのトランスレーター)。 キー/値を属性ハッシュオブジェクトに渡すことができ、これは機能します。 これは、作成および更新時にコントローラーを変更する必要がないことを意味します。

new、create、update_attribute、update_attributesなどのメソッド 正常に動作します。



値を割り当てるだけの場合(たとえば、すぐに保存しないようにするため)、次のようにします。

 ruby-1.9.2-p0 > u[:class] = '1996' => "1996" ruby-1.9.2-p0 > u => #<User id: nil, name: nil, class: "1996", created_at: nil, updated_at: nil>
      
      







一般に、レール生成プロセッサを使用する代わりに、属性の値を直接設定できます。 しかし、私たちはまだ最終決定から一歩離れています。 この属性を残りとして参照したいため、通常のアクセス方法(ゲッターとセッター)のセットを整理する必要があります。 これを行う理由の1つは、この属性の標準検証が利用可能になるためです。



この例のように、プロセッサを追加できます。

 # add to app/models/user.rb def class_name= value self[:class] = value end def class_name self[:class] end
      
      





プロセッサ「class_name」を宣言し、元の属性名の代わりにどこでも使用できるようになりました。 フォームで使用できます:

 <%= f.text_field :class_name %>
      
      





またはバリデーター内:

 validates_presence_of :class_name
      
      





または、新しいオブジェクトを作成するとき:

 User.create :class_name => 'class of 1995'
      
      





コードをダウンロードした場合、これらのアドオンはテスト駆動型です。つまり、メソッド自体を記述する前にこれらのメソッドのテストを記述し、これらのメソッドが正しく機能することを確認します。 同じことをすることをお勧めします。



頑張って



オリジナルあり



All Articles