2016-05-10 12 views
2

Userモデル、Buildingモデル、およびMaintenanceRequestモデルがあります。Ruby on Rails Associationを構築して2つの関連する関連を割り当てよう

ユーザhas_many :maintenance_requestsですが、belongs_to :buildingです。

メンテナンスは、私は、保守要求を作成し、その後、新しいを送信する方法を把握しようとしているbelongs_to :building、およびbelongs_to: user

を要求します。私がやりたいのは何

は次のとおりです。

@maintenance_request = current_user.building.maintenance_requests.build(permitted_mr_params) 
=> #<MaintenanceRequest id: nil, user_id: 1, building_id: 1> 

そしてそれは、親団体だに設定されたユーザーと建物と新しいメンテナンス要求を持っています。私がしなければならない何

@maintenance_request = current_user.maintenance_requests.build(permitted_mr_params) 
@maintenance_request.building = current_user.building 

私は、ユーザーの建物のベースにその建物を設定するためのメンテナンス要求を取得するとよいでしょう。

明らかに、私はこれを回避することができますが、私は構文的な砂糖を本当に感謝します。

+0

アクティブレコードスコープでは、abstrサブクラスまたはコレクションを演じる。後続のメソッドは後者のコレクションに適用されます。だから、基本的に、それ以上のことはできません。 –

+0

ありがとうございます、あなたは絶対に正しいです、これは私がatmで読んでいるものです。 – fbelanger

答えて

1

設定されます

第2引数スコープを呼び出し可能(procまたはlambda)として渡して、特定のレコードセットを取得したり、関連するコレクションにアクセスしたときに生成されたクエリをカスタマイズすることができます。

すなわち

class User < ActiveRecord::Base 
    has_many :maintenance_requests, ->(user){building: user.building}, through: :users 
end 

次にご希望の1行は、あなたがcancancanを使用している場合は、あなたの能力ファイルに

can :create, MaintenanceRequest, user: @user.id, building: @user.building_idをハッシュ条件を追加することができ、またcurrent_user.building.maintenance_requests.build(permitted_mr_params)

を "ただ働き" 必要があります

+0

Omg!ありがとうございますが、私はこれがどういう仕組みか分かりません。私は特定の建物を照会しているように見えますが、あなたが言ったように割り当てます。 – fbelanger

+0

実際、 'current_user.maintenance_requests.build'と書くことができ、ビルディングは引き続き割り当てられます。 – fbelanger

+0

スコープは、ユーザーによってアクセスされたメンテナンス要求にそのスコープが適用されるように、関連付けを変更します。 Railsは、findとbuild/createのスコープを異なる方法で適用する方法を知っています。 – BM5k

1

私の意見では、あなたが提案するアプローチは問題ないと思います。それはもう1行のコードですが、コントローラの複雑さを増やすものではありません。

別のオプションは、あなたのリクエストパラメータで、user_idbuilding_idをマージすることです:

permitted_mr_params.merge(user_id: current_user.id, building_id: current_user.building_id) 
@maintenance_request = MaintenanceRequest.create(permitted_mr_params) 

それとも、あなたは大量の割り当てを懸念していないなら、あなたのフォームで隠しフィールドとしてuser_idbuilding_idを設定しました。しかし、私はパラメムをホワイトリストに載せなければならないので、大きなメリットはありません。

+0

私はあなたが正しいかもしれないと思う、それはセクシーだっただろうが、それは本当に1行を保存するだけです。 – fbelanger

1

私のアプローチは、それがすでに利用者を通してそれに属しているので、

maintenance_request belongs_to :building 

をスキップすることです。代わりに、ユーザーが建物全体に移動することができますので、あなたは完全にmaintenance_request

UPDATE と明示的な建物の関連付けを省略することができ、建物のクラスで

、また
class Building 
    has_many :users 
    has_many :maintenance_requests, through: :users 

    #more stuff 
end 

の方法

class MaintenanceRequest 
    belongs_to :user 

    def building 
     user.building 
    end 

    #more class stuff 
end 

を定義することができますコールバックで自動動作を設定することができます。あなたがそれを行うようにジョブが実行されますが、あなたがユーザーのためにmaintenance_requestを作成するときに、よりRailseyの方法で

ので
class MaintenanceRequest 
    #stuff 
    before_create { 
     building=user.building 
    } 
end 

、建物はhas_manyドキュメントから、それに応じて

+0

しかし、私はまったく同意します...ユーザーは住民や管理者であるため、建物を変更することができます。私ができる限り、あなたが描いていることをやっていますが、私は、ユーザー "current_building"とは関係なく、建物を永続させる方法を見つけることができません。 – fbelanger

+0

私はそのアプローチにも良い点があります。更新中... –

+0

これは、メンテナンスリクエストビルディングが作成時にユーザーのビルディングであるという暗黙のビジネスルールの一種として、これが最も適切な方法かもしれないと思います!非常に素晴らしい! – fbelanger

関連する問題