2

私のアプリには2つのモデルがあります:childそれとhas_many :toysそれtoyですbelongs_to :childchild_idこれを機能させるために必要なdb移行を行いました(toysテーブルに追加)。

最初は、子供は自分で存在し、おもちゃは自分で存在します(関連付けはありません)。幼稚園での毎日の始まりには、子供はおもちゃを持っていません。おもちゃで遊ぶには、子供は最初におもちゃを要求し、その所有者になる必要があります。だから、今私はどういうわけかchild.claim(toy)メソッドを実装する必要があります、そしてここで私は立ち往生しています。具体的には:

  1. childこれはコントローラーまたはモデルに入れる必要がありますか?それとも、どういうわけか両方の間で分割する必要がありますか?
  2. それがコントローラーに入る必要がある場合、それはCRUDアクションの1つに対応する必要がありますか、それともそれ自体が次のようになりdef claim(toy)ますか?

編集1:子はユーザーであり、ブラウザーを介してログオンします。(今日の子供たちは素晴らしいことをすることができます)

4

3 に答える 3

2

子供はおもちゃの外部キーです

これを行う方法は確かに他にもありますが、元の質問に基づいて、最も簡単な解決策は、Toy テーブルのおもちゃに子供が関連付けられているという事実と行動を一致させることです。

最も簡単な解決策

完璧な OOP/MVC 設計で何をすべきかについての議論はさておき、子供がおもちゃを要求すると、その要求は #update (または #請求) Toy コントローラーでのアクション。

子はユーザーであり、ブラウザー経由でログオンします。

あなたの場合、セッションはすでに子が誰であるかを知っているので、Toy モデルに外部キーを追加するのは簡単です。コントローラーは、関連付けられたモデルのパラメーターを受け取るエンティティであるため、特定のおもちゃのどの属性を更新するかを Toy モデルに伝えるのに適した場所です。

確かにもっと複雑な解決策がありますが、元の投稿で提供された情報に基づくと、それらのメリットは疑わしいものです。いつものように、走行距離は異なる場合があります。

于 2012-12-26T14:46:08.243 に答える
2

子供とおもちゃに関するすべてのロジックを処理する別のクラスを作成します。それをコンテキストと呼び、懸念と呼びますが、実行してください。

class ToyChild # or ToyInteraction or ChildContext::Toys...

  attr_reader :toy, :child

  def initialize(toy, chid)
    @toy   = toy
    @child = child
  end

  def associate
    toy.child = child
    # could be more difficult: you should check if the child has not enough toys, if the toy is not already assigned to another child etc...
    #I'd avoid saving here since you may want to perform other operations
  end

  def foo
    #code here
  end

end

そしてコントローラーで:

assoc = ToyChild.new(toy, child).associate
assoc.save

このスタイルのコーディング:

  • テストしやすい

  • 責任を明確に分割する

  • 物事をドライに保ちます(コントローラーに特定のコードはありません)

于 2012-12-26T14:36:28.263 に答える
2

child がユーザーの場合、実際には claim メソッドは必要ありません。claim_toyコントローラーにメソッドを含めることができます。各おもちゃのあなたのおもちゃのインデックス ビューでは、次のようにリンクを付けることができます。

<%= link_to "claim", claim_toy_path(:toy_id => toy.id) %>

コントローラー メソッドは次のようになります。

def claim_toy
  toy = Toy.find(params[:toy_id])
  current_child.toys << toy
end

簡単です。ちなみに、これは安らかな解決策ではありません。

于 2012-12-26T14:38:43.310 に答える