2017-01-20 3 views
2

Rails 5アプリでスコープを使用する方法を学習しようとしています。Rails 5 - 編集アクションのスコープを使用して特定のインスタンスの関連する子を検索する

私は背景の質問hereを尋ねました。

私のRails 5アプリには、ユーザー、プロポーザル、および潜在的なモデルがあります。

ユーザーは自分自身と他のユーザーがコメントを作成できるプロポーザルを作成します。モデル間の

団体は次のとおりです。

ユーザー

has_many :proposals, dependent: :destroy 
    has_many :potentials 

私のroutesファイルで

belongs_to :proposal, inverse_of: :potentials 
    belongs_to :user 

belongs_to :user 
has_many :potentials, inverse_of: :proposal 
    accepts_nested_attributes_for :potentials, reject_if: :all_blank, allow_destroy: true 

潜在的な提案、私は強力ための2つのリソースを持っていますials。私はこのビットでピストを外したかどうかはわかりません。そうでなければこれを行う方法の例を見つけることはできません。提案を行ったユーザーがそれを編集しようとすると私は、ユーザーができるようにすることを望む、

resources :potentials 

など:

resources :proposals do 

    resources :potentials 

が客観私は両方を持っています自分自身で作成したポテンシャルを編集します。

潜在的に2つのルートが設定されている理由は、ネストされたリソースがプロポーザルフォーム内にネストされたフォームフィールドを持つため、プロポーザル作成者がそのような可能性を生むことができるからです。プロポーザルを見て、可能性を秘めた他のユーザーは、別のフォームでそれを行います。

任意のユーザー(プロポーザル作成者を含む)は、その別のフォームを使用して潜在性を編集できます。プロポーザル作成者は、プロポーザルフォームのネストされたフォームによって独自のプロポーザルを編集することもできます。

現時点では、(潜在的なネストされたフィールドを編集しない場合でも)プロポーザルフォームを編集するたびに、プロポーザルの作成者のユーザーIDを挿入して実際の潜在的な作成者のユーザーIDを上書きする可能性があります。

ソリューション

それは彼らだけがUSER_ID == proposal.user_idを持っている場合は、提案/電位を編集することを可能にするように、私は、提案コントローラ内のeditアクションを制限しようとしています。この目的のために

は、私は私のproposal.rb

scope :owner_potentials, ->{ where(user_id: potential.user_id) } 
scope :third_party_potentials, ->{ where(user_id: != potential.user_id) } 

私は上記気に入っスコープを使用して試してみた後の溶液中にスコープを書かれています。スコープはインスタンスではなくクラスを操作するためのものなので、スコープを使用して準拠しているすべてのポテンシャル(potential.user_id = = proposal.user_id)。つまり、ImはProposalクラスを検索せず、Imは特定のプロポーザルを検索します。

This postは、関連するコントローラのアクション内でEvent.allを定義することを提案しましたが、どのようにして特定の電位編集線のみに適用するように制限しましたか?プロポーザル・テーブルでテストするべきではなく、インスタンスだけをテストするべきです。これがうまくいけば、他のすべての提案を除外しようと私の範囲を書き直す必要があると思います。

スコープのあるコントローラで特定のインスタンスで編集アクションを使用する方法はありますか?

答えて

0

私はこのようなスコープを示唆している:

scope :owner_potentials, -> (user_id) { where(user_id: user_id) } 
scope :third_party_potentials, -> (user_id) { where.not(user_id: user_id) } 

あなただけの現在のユーザーのIDを渡す必要があり、これらのスコープを呼び出すとき。

0

スコープは、彼らがで定義されているARクラス。あなたはproposal.rbにowner_potentialsthird_party_potentialsスコープを書かれていると言うためのクエリを定義し。しかし、これらのスコープがポテンシャルのコレクションを返すことを意図している場合は、これらをポテンシャルクラスで定義する必要があります。プロポーザルレコードからこれらのスコープにアクセスする必要がある場合は、スコープを関連付けることができます。

class Potential 
    scope :owner_potentials, -> (user) { where(user: user) } 
    scope :third_party_potentials, -> (user) { where.not(user: user) } 
end 

... 

class ProposalsController # Proposals::PotentialsController..? imo Proposals::PotentialsController#edit sounds like an endpoint for editing exactly one potential record and nothing else, which doesn't sound like what you want. Your call on how to structure the controller/routes though. 
    def edit 
    @proposal = ... # Whatever your logic is to find the proposal 

    @proposal.potentials.owner_potentials(current_user) # do something with the user's potentials 
    @proposal.potentials.third_party_potentials(current_user) # do something with the potentials the user doesn't own 
    end 
end 

スコープ(.owner_potentials)への関連付け(.potentialsを)チェーンどのようにあなたがここで見ることができます。

アソシエーションがある場合、そのアソシエーションをwhereメソッドのフィールドとして扱い、where(user_id: user.id)ではなくwhere(user: user)とすることができます。

最後に、このリファクタでスコープの名前を変更する必要があることに注意してください。 potentials.owner_potentials(user)は少し冗長です。たぶんpotentials.owned_by(user)のようなものでしょうか?

+0

コメントを再入力すると、2つの異なる編集エンドポイントで何を達成しようとしているのか分かりません。あなたのコントローラーが私がここにあるものと異なって見えるようにしたいかもしれません。それにかかわらず、上記のような状況でスコープを管理する方法は上記のとおりです。 – Glyoko

関連する問題