实现“添加到收藏夹"在 Rails 3 &4 [英] Implement "Add to favorites" in Rails 3 & 4

查看:38
本文介绍了实现“添加到收藏夹"在 Rails 3 &4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个应用程序,用户可以在其中创建食谱、查看创建的所有食谱、在会员区查看他们自己的食谱,最后我希望用户将收藏夹"添加到他们的帐户中.

I am building an app where users can create recipes, see all recipes created, view their own recipes in a member area and finally i would like for users to add "favorites" to their account.

我是 Rails 的新手,但已经阅读了文档,这是我对后端应该是什么样子的理解.有人可以确认这看起来是正确的或请提出任何错误的建议,如果我做错了什么(可能是这种情况),请提供解释?

I am new to Rails but have read through docs and this is my understanding of what it should look like in the backend. Could someone confirm that this looks correct or advise of any errors please, with explanations if I have done something wrong (which is probably the case)?

这是我的代码:

用户模型

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

然后我想要一个按钮来发布到数据库,所以我有这个:

I then wanted to have a button to post to the db, so I have this:

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

我想我的路线中可能遗漏了一些东西,但我不确定.

I think I am probably missing something in my routes but I am unsure.

推荐答案

您描述的特定设置混合了多种类型的关联.

The particular setup you describe mixes several types of associations.

首先我们有一个用户模型,其次是一个食谱模型.每个食谱属于一个用户,因此我们有一个 User :has_many recipes, Recipe Being_to :user 关联.此关系存储在配方的 user_id 字段中.

First we have a User model and second a Recipe model. Each recipe belonging to one user, hence we have a User :has_many recipes, Recipe belongs_to :user association. This relationship is stored in the recipe's user_id field.

$ 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) 最喜欢的食谱

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

B) FavoriteRecipe

Next we need to decide on how to implement the story that a user should be able to mark favorite recipes.

这可以通过使用连接模型来完成——我们称之为FavoriteRecipe"——包含列:user_id 和:recipe_id.我们在这里建立的关联是一个has_many :through 关联.

This can be done by using a join model - let's call it FavoriteRecipe - with the columns :user_id and :recipe_id. The association we're building here is a has_many :through association.

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 :通过与模型的关联,我们得到最终结果.

Adding this favorites has_many :through association to the models, we get our final results.

$ 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 中展示的那个.下面描述的解决方案部分是按照那里的投票赞成和反对机制构建的.

D) Controller Actions

There may be several approaches on how to implement Controller actions and routing. I quite like the one by Ryan Bates shown in Railscast #364 on the ActiveRecord Reputation System. The part of a solution described below is structured along the lines of the voting up and down mechanism there.

在我们的 Routes 文件中,我们在名为 favorite 的食谱上添加了一个成员路由.它应该响应发布请求.这将为我们的视图添加一个 favorite_recipe_path(@recipe) url helper.

In our Routes file we add a member route on recipes called favorite. It should respond to post requests. This will add a favorite_recipe_path(@recipe) url helper for our view.

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

在我们的 RecipesController 中,我们现在可以添加相应的收藏操作.在那里我们需要确定用户想要做什么,喜欢还是不喜欢.为此,一个请求参数称为例如可以引入类型,稍后我们也必须将其传递给我们的链接助手.

In our RecipesController we can now add the corresponding favorite action. In there we need to determine what the user wants to do, favoriting or unfavoriting. For this a request parameter called e.g. type can be introduced, that we'll have to pass into our link helper later too.

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

在您的视图中,您可以分别添加收藏和不收藏食谱的链接.

In your view you can then add the respective links to favoriting and unfavoriting recipes.

<% 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 的收藏夹中.

That's it. If a user clicks on the "favorite" link next to a recipe, this recipe is added to the current_user's favorites.

希望对您有所帮助,如有任何问题,欢迎提问.

I hope that helps, and please ask any questions you like.

Rails 关联指南 非常全面,当您获得开始了.

The Rails guides on associations are pretty comprehensives and will help you a lot when getting started.

这篇关于实现“添加到收藏夹"在 Rails 3 &amp;4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆