我正在尝试使用Rails 4创建一个简单的Like /不同按钮。我尝试用社交化宝石做这个,但经过一天的挣扎后我放弃并决定修改M. Hartl的'愚蠢'机制来自Rails教程。这是我到目前为止所得到的:
User.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :validatable
has_many :questions
has_many :answers
has_many :likes, foreign_key: "liker_id", dependent: :destroy
has_many :liked_answers, through: :likes, source: :liked, source_type: "Answer"
def like?(answer)
likes.find_by(liked_id: answer.id)
end
def like!(answer)
likes.create!(liked_id: answer.id)
end
def unlike!(answer)
likes.find_by(liked_id: answer.id).destroy
end
end
Answer.rb:
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :user
has_many :likes, foreign_key: "liked_id",
class_name: "Like",
dependent: :destroy
has_many :likers, through: :likes, source: :liker
end
Like.rb:
class Like < ActiveRecord::Base
belongs_to :liker, class_name: "User"
belongs_to :liked, class_name: "Answer"
validates :liker_id, presence: true
validates :liked_id, presence: true
end
likes_controller.rb:
class LikesController < ApplicationController
skip_before_action :verify_authenticity_token
before_action :authenticate_user!
respond_to :html, :js
def create
@answer = Answer.find(params[:like][:liked_id])
current_user.like!(@answer)
respond_with @answer.question
end
def destroy
@answer = Like.find(params[:id]).liked
current_user.unlike!(@answer)
respond_with @answer.question
end
end
_like.html.erb:
<%= form_for(current_user.likes.build(liked_id: @answer.id), remote: true) do |f| %>
<div><%= f.hidden_field :liked_id %></div>
<%= f.submit "Like!", class: "btn btn-large btn-primary" %>
<% end %>
_unlike.html.erb:
<%= form_for(current_user.likes.find_by(liked_id: @answer.id),
html: { method: :delete }, remote: true) do |f| %>
<%= f.submit "Unlike.", class: "btn btn-large" %>
<% end %>
routes.rb中:
Rails.application.routes.draw do
devise_for :users
scope "/admin" do
resources :users
end
resources :questions do
resources :answers do
get :likes
end
end
resources :likes, only: [:create, :destroy]
root to: 'questions#index'
end
我还在application.js中需要jQuery和jQuery_ujs,以及视图中相关的js.erb文件(“create”和“destroy”)。
'喜欢/不喜欢'机制本身似乎工作得很好 - 在控制台中,我的'喜欢!'并且'不像!'方法,我能够使用id,liker_id和likes_id创建和销毁“Like”对象。
问题始于按钮本身。
我可以看到“喜欢!”每个答案旁边的按钮,但是当我点击它时 - 我收到此错误:
ActiveRecord::RecordNotFound in LikesController#create
Couldn't find Answer with 'id'=
LikesController中此行的错误点:
@answer = Answer.find(params[:like][:liked_id])
所以我认为我的@ answer.id结果为'nil',但我不知道我在哪里弄错了。我的第一个猜测是路线文件 - 我仍然不确定那里的一切是否正确。
我花了一整天时间寻找解决方案,我也在SO上找到了一些类似的问题,但没有一个答案可以帮助我。
非常感谢任何想法。
编辑:错误中的参数
Parameters:
{"utf8"=>"✓",
"like"=>{"liked_id"=>""},
"commit"=>"Like!"}
答案 0 :(得分:0)
您使用隐藏字段标记时出错了。 http://api.rubyonrails.org/v4.1.1/classes/ActionView/Helpers/FormHelper.html#method-i-hidden_field表示您需要在标记中提供两个值。将您的ERB文件更改为:
_like.html.erb:
<%= form_for(current_user.likes.build(liked_id: @answer.id), remote: true) do |f| %>
<div><%= f.hidden_field :liked_id, :value => @answer.id %></div>
<%= f.submit "Like!", class: "btn btn-large btn-primary" %>
<% end %>
那应该可以得到你想要的东西。