9

Railsプロジェクトのインポート可能な懸念を書いているところです。この懸念は、csv ファイルを Importable を含む任意のモデルにインポートするための一般的な方法を提供します。

モデルごとに、インポート コードが既存のレコードを検索するために使用するフィールドを指定する方法が必要です。懸念事項に対してこのタイプの構成を追加する推奨される方法はありますか?

4

2 に答える 2

11

もう少し「普通に見える」解決策です。懸念に引数を渡す必要を避けるために (偶然にも、正確にいくつかの csv インポートの問題のために) これを行います。エラーを発生させる抽象メソッドには長所と短所があると確信していますが、すべてのコードを app フォルダーと、それが見つかると予想されるモデルに保持します。

「懸念」モジュールでは、基本のみ:

module CsvImportable
  extend ActiveSupport::Concern

  # concern methods, perhaps one that calls 
  #   some_method_that_differs_by_target_class() ...

  def some_method_that_differs_by_target_class()
    raise 'you must implement this in the target class'
  end

end

そして、懸念のあるモデルでは:

class Exemption < ActiveRecord::Base
  include CsvImportable

  # ...

private
  def some_method_that_differs_by_target_class
    # real implementation here
  end
end
于 2014-06-26T22:37:23.867 に答える
9

各モデルに懸念事項を含めるのではなく、ActiveRecordサブモジュールを作成してそれを拡張ActiveRecord::Baseし、そのサブモジュールにインクルードを行うメソッド (たとえばinclude_importable) を追加することをお勧めします。次に、フィールド名を引数としてそのメソッドに渡し、メソッドでインスタンス変数とアクセサー (たとえば ) を定義して、クラスとインスタンス メソッドimportable_fieldで参照するためにフィールド名を保存します。Importable

だから、このようなもの:

module Importable
  extend ActiveSupport::Concern

  module ActiveRecord
    def include_importable(field_name)

      # create a reader on the class to access the field name
      class << self; attr_reader :importable_field; end
      @importable_field = field_name.to_s

      include Importable

      # do any other setup
    end
  end

  module ClassMethods
    # reference field name as self.importable_field
  end

  module InstanceMethods
    # reference field name as self.class.importable_field
  end

end

次に、この行を初期化子 ( )ActiveRecordに入れるなどして、このモジュールで拡張する必要があります。config/initializers/active_record.rb

ActiveRecord::Base.extend(Importable::ActiveRecord)

(懸念がある場合は、config.autoload_pathsここで要求する必要はありません。以下のコメントを参照してください。)

次に、モデルに次Importableのように含めます。

class MyModel
  include_importable 'some_field'
end

そして、imported_fieldリーダーはフィールドの名前を返します:

MyModel.imported_field
#=> 'some_field'

ではInstanceMethods、フィールドの名前を に渡すことで、インポートされたフィールドの値をインスタンス メソッドに設定し、次write_attributeを使用して値を取得できますread_attribute

m = MyModel.new
m.write_attribute(m.class.imported_field, "some value")
m.some_field
#=> "some value"
m.read_attribute(m.class.importable_field)
#=> "some value"

それが役立つことを願っています。これは私の個人的な見解にすぎませんが、他にも方法があります (それらについても知りたいです)。

于 2013-01-13T04:18:02.847 に答える