在Rails 3和4中实现“添加到collections夹”

我正在构build一个应用程序,用户可以创build食谱,查看所有创build的食谱,在会员区查看自己的食谱,最后我想让用户在他们的账户中添加“collections夹”。

我是Rails的新手,但已经通读了文档,这是我对后端应该看起来像什么的理解。 有人可以证实,这看起来是正确的或build议的任何错误请解释,如果我做了错误的(可能是这样的)?

所以这是我的代码:

用户模型

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 

collections夹控制器

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

然后我想有一个button后,数据库,所以我有这样的:

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

我想我可能在我的路线中错过了一些东西,但我不确定。

您描述的特定设置混合了几种types的关联。

A)用户和配方

首先,我们有一个用户模型,第二个食谱模型。 每个食谱属于一个用户,因此我们有一个用户:has_many食谱,食谱belongs_to:用户关联。 这种关系存储在配方的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

接下来,我们需要决定如何实现用户应该能够标记喜欢的食谱的故事。

这可以通过使用连接模型来完成 – 让我们把它称为FavoriteRecipe – 使用列:user_id和:recipe_id。 我们在这里build立的协会是一个has_many:通过协会。

 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 

添加这个collectionshas_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)控制器操作

有关如何实施控制器操作和路由可能有几种方法。 我非常喜欢Ryan Bates在ActiveRecord声誉系统Railscast#364中所展示的那个。 下面描述的解决scheme的一部分是沿着这里的投票上下机制的线构build的。

在我们的Routes文件中,我们在名为favorite的食谱中添加一个成员路线。 它应该回复发布的请求。 这将为我们的视图添加一个favorite_recipe_path(@recipe)url助手。

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

在我们的RecipesController中,我们现在可以添加相应的collections夹操作。 在那里,我们需要确定用户想要做什么,喜欢或不喜欢。 为此,可以引入一个名为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 %> 

而已。 如果用户点击配方旁边的“collections”链接,则此配方将添加到current_user的collections夹中。

我希望有所帮助,请问你喜欢的任何问题。

关于关联Rails指南非常全面,在开始时会帮助你很多。

谢谢你的指导,托马斯! 它工作很好。

只是想补充一点,为了让您最喜欢的方法正常工作,您需要将文本换成双引号而不是单引号,以便string插值function正常工作。

 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

这个线程是超级有用的!

谢谢!

不要忘记在表单标签中包含=

 <% 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 %> 

所选的答案是非常好的,但我不能发表评论,我真的有一个关于上述问题。 你怎么能限制一个用户有一个最喜欢的食谱? 用上面的答案,用户可以继续按最喜欢的和许多条目将被创build在数据库中…