我正在开发一个Rails应用程序,允许用户使用Food2Fork API搜索和浏览食谱。
版本: Rails 5.0.0.1,ruby 2.3.1p112(2016-04-26修订版54768)[x64-mingw32]
我有用户模型,配方模型和收藏夹模型。我试图允许登录到他们找到的最喜欢的食谱的用户。要明确的是,搜索和浏览都可以使用配方,以及登录/注销用户,因此我知道这不是用户自己或访问API的问题。
尝试实现此收藏系统时,打开视图时出现以下错误(代码位于底部):
undefined method `relation_delegate_class' for Recipe:Class
用户模型:
class User < ApplicationRecord
has_secure_password
has_many :favorites
has_many :favorite_recipes, through: :favorites, source: :favorited, source_type: 'Recipe'
end
食谱模型:
require 'httparty'
class Recipe
include HTTParty
#define API base URL and key for project
ENV['FOOD2FORK_API_KEY'] = 'api_key_here' # (this was edited so I don't make my key public)
base_uri 'http://food2fork.com/api'
default_params key: ENV['FOOD2FORK_API_KEY']
format :json
#search method
def self.for term
get('/search', query: { q: term }) ["recipes"]
end
#show method
def self.find term
get('/get', query: { rId: term }) ["recipe"]
end
def self.browse term
get('/browse', query: { q: term }) ["recipes"]#random number
end
end
最喜欢的型号:
class Favorite < ApplicationRecord
belongs_to :user
belongs_to :favorited, polymorphic: true
end
用户控制器:
class UsersController < ApplicationController
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
session[:user_id] = @user.id
redirect_to '/home'
else
redirect_to '/register'
end
end
private
def user_params
params.require(:user).permit(:username, :email, :password, :location, :fname, :lname)
end
end
食谱控制器:
class RecipesController < ApplicationController
def search
@search_term = params[:ingredient]
@recipes = Recipe.for(@search_term)
end
def show
@id_r = params[:id]
@recipe = Recipe.find(@id_r)
end
def browse
@rand_num = params[:random]
@rand_recipes = Recipe.for(@rand_num)
end
end
最喜欢的控制器:
class FavoriteRecipesController < ApplicationController
before_action :set_recipe
def create
if Favorite.create(favorited: @recipe, user: current_user)
redirect_to @recipe, notice: 'Recipe favorited'
else
redirect_to @recipe, alert: 'Something went wrong.'
end
end
def destroy
Favorite.where(favorited_id: @recipe.rId, user_id: current_user.id).first.destroy
redirect_to @recipe, notice: 'Recipe unfavorited.'
end
private
def set_recipe
@recipe = Recipe.find(params[:recipe_id] || params[:id])
end
end
数据库架构:
ActiveRecord::Schema.define(version: 20161123033852) do
create_table "favorite_recipes", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.integer "recipe_id"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "favorites", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.integer "user_id"
t.string "favorited_type"
t.integer "favorited_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["favorited_type", "favorited_id"], name: "index_favorites_on_favorited_type_and_favorited_id", using: :btree
t.index ["user_id"], name: "index_favorites_on_user_id", using: :btree
end
create_table "users", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
t.string "username"
t.string "email"
t.string "password_digest"
t.decimal "location", precision: 10
t.string "fname"
t.string "lname"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_foreign_key "favorites", "users"
end
最后,在recipes / show.html中的视图:
<% this_recipe = @recipe %>
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
</div>
<div class="container-fluid bg-grey" style="text-align:center">
<h1><%= this_recipe["title"] %></strong></h1>
<% if (this_recipe.nil? or this_recipe == []) %>
<p> <h2><strong>Sorry</b>, that recipe doesn't exist.</h2></p>
<% else %>
<center><div class="recipebox" style="padding:20px;margin:10px; border:1px solid orange; background:white;width:75%">
<div class="row">
<div class="col-md-6">
<p><%= link_to(image_tag(this_recipe["image_url"], height: '400', width: '400'), this_recipe["source_url"])%><br/>
(<%= link_to("View Recipe Source", this_recipe["source_url"]) %>)</p>
</div>
<div class="col-md-6">
<h2>Ingredients:</h2>
<% ingredients = this_recipe["ingredients"] %>
<% ingredients.each do |i| %>
• <%= i %> <br/>
<% end %>
<p>
<%- unless current_user.favorite_recipes.exists?(id: @recipe.rId) -%>
<%= link_to 'Add to favorites', favorite_recipes_path(recipe_id: @project), method: :post %>
<%- else -%>
<%= link_to 'Remove from favorites', favorite_recipe_path(@recipe), method: :delete %>
<%- end -%>
</div>
<% end %>
</center>
</div>
</div>
</div>
我不确定我是否没有正确地关联模型,我没有正确传递信息,或者究竟是什么导致了这个错误。感谢您解决这个问题的任何帮助。
修改
跟踪:
activerecord (5.0.0.1) lib/active_record/relation/delegation.rb:106:in `relation_class_for'
activerecord (5.0.0.1) lib/active_record/relation/delegation.rb:100:in `create'
activerecord (5.0.0.1) lib/active_record/associations/collection_association.rb:47:in `reader'
activerecord (5.0.0.1) lib/active_record/associations/builder/association.rb:111:in `favorite_recipes'
app/views/recipes/show.html.erb:32:in `_app_views_recipes_show_html_erb___356804060_113751160'
actionview (5.0.0.1) lib/action_view/template.rb:158:in `block in render'
activesupport (5.0.0.1) lib/active_support/notifications.rb:166:in `instrument'
actionview (5.0.0.1) lib/action_view/template.rb:348:in `instrument'
actionview (5.0.0.1) lib/action_view/template.rb:156:in `render'
actionview (5.0.0.1) lib/action_view/renderer/template_renderer.rb:54:in `block (2 levels) in render_template'
actionview (5.0.0.1) lib/action_view/renderer/abstract_renderer.rb:42:in `block in instrument'
activesupport (5.0.0.1) lib/active_support/notifications.rb:164:in `block in instrument'
activesupport (5.0.0.1) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (5.0.0.1) lib/active_support/notifications.rb:164:in `instrument'
actionview (5.0.0.1) lib/action_view/renderer/abstract_renderer.rb:41:in `instrument'
actionview (5.0.0.1) lib/action_view/renderer/template_renderer.rb:53:in `block in render_template'
actionview (5.0.0.1) lib/action_view/renderer/template_renderer.rb:61:in `render_with_layout'
日志:
ActionView::Template::Error (undefined method `relation_delegate_class' for Recipe:Class):
29: <% end %>
30:
31: <p>
32: <%- unless current_user.favorite_recipes.exists?(id: @recipe.rId) -%>
33: <%= link_to 'Add to favorites', favorite_recipes_path(recipe_id: @recipe), method: :post %>
34: <%- else -%>
35: <%= link_to 'Remove from favorites', favorite_recipe_path(@recipe), method: :delete %>
app/views/recipes/show.html.erb:32:in `_app_views_recipes_show_html_erb___356804060_113751160'
Rendering C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout
Rendering C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
Rendered C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (6.0ms)
Rendering C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
Rendered C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.9ms)
Rendering C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
Rendered C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (2.0ms)
Rendered C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout (1241.0ms)
答案 0 :(得分:0)
对于基本用途,这是通过has_and_belongs_to_many
关系完成的。参见:
http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association
如果您想了解有关收藏模式的更多信息,而不仅仅是用户收藏食谱的事实,您可以将其分解为自己的类。
(警告:从头开始打字,尚未经过测试......但想法就在那里)
class Favorite
belongs_to :user
# has a recipe_id field that's linked to the id of Recipe on Food2Fork API
def recipe
#... code to get a recipe from id ...
end
end
class User
has_many :favorites
def favorite!(recipe)
self.favorites.create(:recipe_id => recipe.id)
end
end
答案 1 :(得分:0)
我按照this教程,轻松地在我的应用中设置了一个优惠系统。您可以使用以下实现并在您的应用程序中进行设置。