2

UserService バックエンド Rails アプリの 3 つのモデル:

class User < ActiveRecord::Base
  has_many :services
  has_many :members
  has_many :groups, :through => :members
  has_many :managed_groups, :class_name => "Group"
  accepts_nested_attributes_for :managed_groups, :services, :groups
end

class Group < ActiveRecord::Base
  has_many :members
  has_many :users, :through => :members
  belongs_to :manager, :class_name => "User", :foreign_key => :user_id 
  accepts_nested_attributes_for :users  
end

class Service < ActiveRecord::Base
  belongs_to :user
end

class Member < ActiveRecord::Base
  belongs_to :group
  belongs_to :user
end

別の Rails フロントエンドにある 3 つの ActiveResource モデル

class User < ActiveResource::Base
  self.site = "http://localhost:8801"
end

class Group < ActiveResource::Base
  self.site = "http://localhost:8801"
end

class Service < ActiveResource::Base
  self.site = "http://localhost:8801"
end

フロントエンドから、それは行うために動作します

Service.first.user_id = User.first

Service.user_id は belongs_to であるため、単一のプロパティです。

しかし、私はどちらもできません

User.first.groups << Group.first

また

Group.first.users << User.first

ActiveResource は GET リクエストを生成しているだけなので、何も起こりません。

完全を期すために、(フロントエンドで) 次のようなことを行うことも失敗します。

u = User.first
g = Group.first
u.groups.push(g)

等々。users_controller::update メソッドを使用するとうまくいくと思っていましたが、これが可能かどうか疑問に思っています。

2 つの ActiveResource モデルで :has_many, :through を実行した人はいますか? AR モデルのコレクションに影響を与える方法はありますか? 結合テーブルを手動で操作する必要がありますか? (それによって members_controller を作成しますか?)

4

1 に答える 1

0

これは、StackOverflowよりもコアチームにとっては何かかもしれません。

ActiveResourceがRESTfulクライアントとの通信方法について愚かであるか、ActiveRecordが1つをリッスンする方法について愚かであるようです(または、代替の、そしてはるかに可能性の高いオプションである、これら2つのことは基本的に通信できませんお互いに。)

上記のユーザー、サービス、およびグループを指定すると、フロントエンドは/users/1.xmlのバックエンドサーバーにPUTリクエストを送信すると、バックエンドは次のパラメーターをログに記録します(簡潔にするために一部の値は削除されています) :

{"user"=>
  {"created_at"=>2011-06-23 02:58:15 UTC, 
   "id"=>1, 
   "name"=>"John Metta", 
   "updated_at"=>2011-06-23 02:58:15 UTC, 
   "managed_groups"=>[], 
   "services"=>[
     {"created_at"=>2011-06-23 02:58:15 UTC, 
      "id"=>1, 
      "updated_at"=>2011-06-23 02:58:15 UTC, 
      "user_id"=>1}
   ], 
   "groups"=>[
     {"created_at"=>2011-06-23 02:56:37 UTC, 
      "id"=>1, 
      "updated_at"=>2011-06-23 02:56:37 UTC,  
      "user_id"=>nil, 
      "users"=>[
        {"created_at"=>2011-06-23 03:36:28 UTC, 
         "id"=>6, 
         "name"=>"Jefferey", 
         "updated_at"=>2011-06-23 03:36:28 UTC}, 
        {"created_at"=>2011-06-23 02:59:36 UTC, 
         "id"=>2, 
         "name"=>"George", 
         "updated_at"=>2011-06-23 03:05:13 UTC}
       ]
     }, 
     {"created_at"=>2011-06-23 02:56:37 UTC, 
      "id"=>1, 
      "name"=>"Site Admin", 
      "updated_at"=>2011-06-23 02:56:37 UTC, 
      "user_id"=>nil, 
      "users"=>[
        {"created_at"=>2011-06-23 03:36:28 UTC, 
         "id"=>6, 
         "name"=>"Jefferey", 
         "updated_at"=>2011-06-23 03:36:28 UTC}, 
        {"created_at"=>2011-06-23 02:59:36 UTC, 
         "id"=>2, 
         "name"=>"George", 
         "updated_at"=>2011-06-23 03:05:13 UTC}, 
        {"created_at"=>2011-06-23 02:58:15 UTC, 
         "id"=>1, 
         "name"=>"John Metta", 
         "updated_at"=>2011-06-23 02:58:15 UTC}
       ]
     }
   ]
  },
  "id"=>"1"}

したがって、ActiveResourceに関するいくつかの問題(または、おそらく、ActiveResourceをどのように使用しようとしているのか)を確認できますが、主なものは次のとおりです。

ActiveResourceは関連付けについて何も知らないように見えるので、すべてをばかげた方法でバンドルするだけです。言い換えれば、ActiveResourceは、これが実際に機能するためには、「うーん、あなたはグループのリスト。Groupは別のモデルです。これをgroups_attributesと呼び、もう一方の端のグループのリストに再構築できるようにします。

さて、私が炎上する前に、「groups_attributes」はActiveRecordの語彙であり、一般的なREST単語ではないことを理解しています。したがって、ActiveResourceがそれを使い始めると、たとえば、Scalaで実行される他のバックエンドが壊れてしまいます。

ただし、RailsがRailsと連携できる必要があり、ActiveResourceがそれについて愚かである必要があることを考えると、ActiveRecordは、「この着信RESTfulモデルには、既知のモデルにマップするオブジェクトが含まれていることを理解できるはずです。参照されているので、それらのモデルを作成して機能させてみましょう。

実行可能なソリューション:

ActiveRecordが常に自動的に着信パラメーターセットに含まれているMODELという名前のパラメーターをMODELにマップしようとするはずだと仮定して、これについて十分に考えていませんでした。それには、もう少しテストと思考が必要になります。ただし、私の解決策は、users_controllerで設定された着信パラメーターを次のようなものでキャッチすることでした。

  …
  begin
    groups = []
    params[:user][:groups].each do |g|
      groups << Group.find(g[:id])
    end
    params[:user][:groups] = groups
  rescue
    # Do something not incredibly stupid here
  end
  …

これは物事を比較的きれいにつかむようです。私の恐れは、これはRailsにとってかなりかさばるように見えることです。これは通常、物事に対してはるかにエレガントなソリューションを備えていますが、基本的なものが欠けています。

(完了のために、そのパラメータ文字列には他にも問題があることに気付きました。たとえば、グループをユーザーにバンドルし、ユーザーをグループにバンドルしているため、必然的に大量のデータを渡します( 、グループ全体、およびそのすべてのユーザー)ユーザーを渡すとき。これには、グループIDのリストなど、ある種のプロキシが必要です。おそらく、ActiveResourceモデルには、これらのオブジェクトをラップするメソッドが必要です。検討中です。この問題の範囲外の問題。)

于 2011-06-23T15:48:39.180 に答える