1

これは 1 日 1/2 の間私をイライラさせてきました。

通常とは異なる場所にあるモジュール .rb ファイルからモデルを拡張しようとしています。私のモデルでは、モデルの属性に基づいてモジュールに拡張しようとしています。モデルはビューに渡され、モデルのパス属性に関係なく、常にビューが同じモジュール メソッド (「コンテンツ」) を呼び出すようにします。

 Test < ActiveRecord::Base
   ...
   after_initialization do |test|
     if !self.path.nil?
       if File.exists?('app/views/' + self.path + '/_extend.rb')
         extend 'app/views/' + self.path + '/_extend'
       end
     end
   end
   ...
 end

別のファイルからクラスメソッドを動的に追加しようとしています。物事を整理しておきたいので、すべてのモジュール メソッドを巨大なスイッチ ケースを使用してモデルに詰め込みたいと考えています。

助言がありますか?ありがとう。

4

1 に答える 1

2

rubyのextendメソッドはパスでは機能しません。拡張したいモジュールを提供する必要があります。したがって、保存するのpathではなく、type後で拡張するモジュールへの参照を取得するために使用できるようなものを保存する必要があります。ちょっとした例:

module GuestBehavior
  def has_access?
    false
  end
end

module AdminBehavior
  def has_access?
    true
  end
end

class User < ActiveRecord::Base
  after_initialize :extend_behavior

  def extend_behavior
    return if kind.blank?
    behavior_module = "#{kind.capitalize}Behavior".constantize
    extend behavior_module
  end
end

admin = User.new(:kind => 'admin')
guest = User.new(:kind => 'guest')

admin.has_access? # => true
guest.has_access? # => false

これは、私が実際に作成するコードよりも実験的なものです。それはあなたにあなたの目標を達成する方法のアイデアを与えるはずです。

編集:モジュールを別の場所に配置したい場合は、簡単に機能させることができます。レールを使用していると仮定すると、オートローダーがあります。未定義の定数にアクセスすると、オートローダーが起動し、その定数を定義するファイルをロードしようとします。上記の例は次のようになります。

app/models/guest_behavior.rb
app/models/admin_behavior.rb

requireコードにステートメントを入れる必要はありません。GuestBehaviorまたはにアクセスすると、Railsはファイルを自動的にロードしますAdminBehavior。(それはconstantize呼び出しが行うことです)

于 2013-01-06T00:53:52.713 に答える