2016-11-23 104 views
0

我正在研究Rails應用程序,該應用程序允許用戶使用Food2Fork API來搜索和瀏覽食譜。在Rails中添加用戶收藏夾

版本: 導軌5.0.0.1,紅寶石2.3.1p112(2016年4月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 

Recipe模型:

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 

最後,看來,在配方/ 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| %> 
&#0149; <%= 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

添加了跟蹤以及日誌,如果這可能也有幫助。 @maxpleaner – crackedact0r

+0

它看起來不像你的食譜類真的是一個ApplicationRecord模型。也許這個HTTParty的東西可以被提取到一個單獨的類中。除此之外,我不確定。 –

回答

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 
+0

這是現在我做出這些改變後的錯誤:未定義的方法'has_many'食譜:Class @Hong – crackedact0r

+0

他們是函數簽名,並不完全代表您的用例,但我已經調整了一下,以適應食譜是一個HTTParty類的事實。這裏的一般想法是'Favorites#belongs_to:user',並以某種方式引用配方的id。這就是你用來將兩者聯繫在一起的原因。 – Hong

0

我跟着this教程,並得到了favouriting系統在我輕鬆的應用程序設置。您可以使用以下實現並在您的應用程序中進行設置。

+0

這實際上是我所追求的,我一步一步地在教程中做了一切。 – crackedact0r