1

Rails で、ActiveRecord ではなく LDAP データベースからユーザーを取得するモデルを作成しました。現在、ActiveRecord モデルを LDAP ベースのモデルと統合しようとしているので、いくつかの一般的な ActiveRecord メソッドをエミュレートするメソッドをモデルに記述しています。

私がエミュレートしようとしているメソッドの 1 つは、ActiveRecord の has_many スルー リレーションシップによって通常作成されるメソッドです。ActiveRecord では、この関係により次のことが可能になります。

user = User.first
groups = user.groups # == Array of Groups
groups << Group.create(name: "Test") # How does Rails allow this?

Railsはこれをどのように許可していますか? user.groups によって返された配列インスタンスにメソッドを動的に割り当てようとしましたが、配列が作成されたユーザー レコードをこれらのメソッドに認識させる方法はないようです。(そのため、彼らは新しい関係レコードを割り当てることができuser_idます。) 何が欠けていますか?

4

2 に答える 2

2

グループの配列のように見えuser.groupsますが、実際には完全に別のクラスです。関連付けプロキシと呼ばれる、通常あまり知られていない Rails の内部クラスです。<<プロキシは、create、などのメソッドに応答してnew、リクエストをターゲット クラスにプロキシし、関連付けを適切に設定します。

同様の機能が必要な場合は、独自の種類のプロキシ アソシエーションを実装する必要があります。そうするのはかなり複雑ですが、これで始められるかもしれません。

module LDAP
  class Association
    attr_accessor :source, :target

    def initialize(source, target)
      @source = source
      @target = target
    end

    def <<(obj)
      @source.group_ids = [group_ids + obj].flatten.uniq
      @source.save
    end

  end
end

class User
  def groups
    LDAP::Association.new(self, Group)
  end
end

これは、ActiveRecord がアソシエーション プロキシを実装する方法に特に近いわけではありません。ただし、これは ActiveRecord のソリューションよりもかなり単純であり、いくつかの基本的な ActiveRecord 機能を複製するのに十分なはずです。

于 2012-07-26T16:28:50.757 に答える
0

Rails のソース コードを調べて、これを実行します。たとえば、上記の Group.create の例のコードは、次の場所にあります。

http://api.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html

  def create(attributes = nil, options = {}, &block)
    if attributes.is_a?(Array)
      attributes.collect { |attr| create(attr, options, &block) }
    else
      object = new(attributes, options, &block)
      object.save
      object
    end
  end
end
于 2012-07-26T16:36:02.807 に答える