30

私は、ユーザーがレシピを作成し、作成されたすべてのレシピを表示し、メンバーエリアで自分のレシピを表示できるアプリを構築しています。最後に、ユーザーが自分のアカウントに「お気に入り」を追加したいと思います。

私はRailsを初めて使用しますが、ドキュメントを読み通しました。これは、バックエンドでどのように表示されるかを理解したものです。誰かがこれが正しいように見えることを確認したり、エラーがあればアドバイスしてください。私が何か間違ったことをした場合は説明を付けてください(おそらくそうです)。

だからこれは私のコードです:

ユーザーモデル

has_many :recipes
has_many_favorites, :through => :recipes

レシピモデル

belongs_to :user
has_many :ingredients #created seperate db for ingredients
has_many :prepererations #created seperate db for prep steps

好きなモデル

belongs_to :user
has_many :recipes, :through => :user
#this model has one column for the FK, :user_id

お気に入りコントローラー

def create
  @favrecipes =current_user.favorites.create(params[:user_id])
end

次に、データベースに投稿するためのボタンが必要だったので、次のようにします。

<%= button_to("Add to Favorites" :action => "create", :controller => "favorites" %>

私はおそらく私のルートで何かが欠けていると思いますが、私は確信が持てません。

4

4 に答える 4

71

説明する特定の設定では、いくつかのタイプの関連付けが混在しています。

A)ユーザーとレシピ

最初にユーザーモデルがあり、次にレシピモデルがあります。各レシピは1人のユーザーに属しているため、User:has_manyレシピ、レシピbelongs_to:userアソシエーションがあります。この関係は、レシピのuser_idフィールドに保存されます。

$ rails g model Recipe user_id:integer ...
$ rails g model User ...

class Recipe < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :recipes
end

B)FavoriteRecipe

次に、ユーザーがお気に入りのレシピにマークを付けることができるようにするストーリーを実装する方法を決定する必要があります。

これは、:user_id列と:recipe_id列を持つ結合モデル(FavoriteRecipeと呼びましょう)を使用して実行できます。ここで構築しているアソシエーションは、has_many:throughアソシエーションです。

A User  
  - has_many :favorite_recipes  
  - has_many :favorites, through: :favorite_recipes, source: :recipe

A Recipe
  - has_many :favorite_recipes  
  - has_many :favorited_by, through: :favorite_recipes, source: :user 
      # returns the users that favorite a recipe

このお気に入りのhas_manyをモデルに関連付けることで、最終結果が得られます。

$ rails g model FavoriteRecipe recipe_id:integer user_id:integer

# Join model connecting user and favorites
class FavoriteRecipe < ActiveRecord::Base
  belongs_to :recipe
  belongs_to :user
end

---

class User < ActiveRecord::Base
  has_many :recipes

  # Favorite recipes of user
  has_many :favorite_recipes # just the 'relationships'
  has_many :favorites, through: :favorite_recipes, source: :recipe # the actual recipes a user favorites
end

class Recipe < ActiveRecord::Base
  belongs_to :user

  # Favorited by users
  has_many :favorite_recipes # just the 'relationships'
  has_many :favorited_by, through: :favorite_recipes, source: :user # the actual users favoriting a recipe
end

C)協会との交流

##
# Association "A"

# Find recipes the current_user created
current_user.recipes

# Create recipe for current_user
current_user.recipes.create!(...)

# Load user that created a recipe
@recipe = Recipe.find(1)
@recipe.user

##
#  Association "B"

# Find favorites for current_user
current_user.favorites

# Find which users favorite @recipe
@recipe = Recipe.find(1)
@recipe.favorited_by # Retrieves users that have favorited this recipe

# Add an existing recipe to current_user's favorites
@recipe = Recipe.find(1)
current_user.favorites << @recipe

# Remove a recipe from current_user's favorites
@recipe = Recipe.find(1)
current_user.favorites.delete(@recipe)  # (Validate)

D)コントローラーのアクション

コントローラのアクションとルーティングを実装する方法には、いくつかのアプローチがあります。ActiveRecordレピュテーションシステムのRailscast#364に示されているRyanBatesによるものがとても気に入っています。以下で説明するソリューションの一部は、そこでの投票の上下メカニズムに沿って構成されています。

ルートファイルで、お気に入りと呼ばれるレシピにメンバールートを追加します。投稿リクエストに応答する必要があります。これにより、ビューにfavorite_recipe_path(@recipe)URLヘルパーが追加されます。

# config/routes.rb
resources :recipes do
  put :favorite, on: :member
end

RecipesControllerで、対応するお気に入りのアクションを追加できるようになりました。そこでは、ユーザーが何をしたいのか、賛成か反対かを判断する必要があります。このために、eg typeと呼ばれるリクエストパラメータを導入できます。これは、後でリンクヘルパーにも渡す必要があります。

class RecipesController < ...

  # Add and remove favorite recipes
  # for current_user
  def favorite
    type = params[:type]
    if type == "favorite"
      current_user.favorites << @recipe
      redirect_to :back, notice: 'You favorited #{@recipe.name}'

    elsif type == "unfavorite"
      current_user.favorites.delete(@recipe)
      redirect_to :back, notice: 'Unfavorited #{@recipe.name}'

    else
      # Type missing, nothing happens
      redirect_to :back, notice: 'Nothing happened.'
    end
  end

end

次に、ビューで、お気に入りのレシピとお気に入りのレシピへのそれぞれのリンクを追加できます。

<% if current_user %>
  <%= link_to "favorite",   favorite_recipe_path(@recipe, type: "favorite"), method: :put %>
  <%= link_to "unfavorite", favorite_recipe_path(@recipe, type: "unfavorite"), method: :put %>
<% end %>

それでおしまい。ユーザーがレシピの横にある「お気に入り」リンクをクリックすると、このレシピがcurrent_userのお気に入りに追加されます。

お役に立てば幸いです。ご不明な点がございましたら、お気軽にお問い合わせください。

アソシエーションに関するRailsガイドは非常に包括的であり、開始するときに大いに役立ちます。

于 2012-11-05T21:10:43.283 に答える
1

ガイドをありがとう、トーマス!それはうまくいきます。

お気に入りのメソッドが正しく機能するためには、テキストを一重引用符ではなく二重引用符で囲んで、文字列補間を機能させる必要があることを追加したかっただけです。

redirect_to :back, notice: 'You favorited #{@recipe.name}'

->

redirect_to :back, notice: "You favorited #{@recipe.name}"

https://rubymonk.com/learning/books/1-ruby-primer/chapters/5-strings/lessons/31-string-basics

于 2016-07-23T00:19:53.373 に答える