繁体   English   中英

未定义的方法`vote_for_song_songs_path'[rails 4]

[英]undefined method `vote_for_song_songs_path' [rails 4]

因此,我在让Thumbs Up gem正常工作时遇到了麻烦。

我已按照本教程进行操作,但似乎出现了以下错误:

错误消息:

NoMethodError in Songs#index

Showing /Users/apane/Downloads/leap_stage/leap_stage/app/views/songs/index.html.erb where line #10 raised:

undefined method `vote_for_song_songs_path' for #<#<Class:0x007fd0b60203d0>:0x007fd0b26ecdc0>

<li><%= link_to song.title, song %><br></li>
Submitted <%= time_ago_in_words(song.created_at) + " ago" %>
<span class="comments"> | <%= pluralize(song.comments.size, 'comment') %></span><br />
<%=link_to image_tag('thumbs_up', :border => 0), vote_for_song_songs_path(@song), :remote => true %>
<%=link_to image_tag('thumbs_down', :border => 0), vote_against_song_songs_path(@song), :remote => true %> 

index.html.erb

<div id="layout1">

<h3>Songs</h3>

<ol>
<% @songs.each do |song| %>
 <li><%= link_to song.title, song %><br></li>
    Submitted <%= time_ago_in_words(song.created_at) + " ago" %>
    <span class="comments"> | <%= pluralize(song.comments.size, 'comment') %></span><br />
 <%=link_to image_tag('thumbs_up', :border => 0), vote_for_song_songs_path(@song), :remote => true %>
 <%=link_to image_tag('thumbs_down', :border => 0), vote_against_song_songs_path(@song), :remote => true %>


<%#= link_to 'Show', song, class: "button small secondary" %>
<%= link_to('Edit', edit_song_path(song), class: "button small secondary") if can? :update, @song %>
<%= link_to('Destroy', song, method: :delete, data: {confirm: 'Are you sure?'}, class: "button small secondary") if can? :destroy, @song %>


<% end %>

</ol>
</div>


<br />
</div>

song_controller.rb

class SongsController < ApplicationController
  before_filter :authenticate_user!, only: [:create ,:edit, :update, :destroy, :vote_for_song]
  before_action :set_song, only: [:show, :edit, :update, :destroy, :vote_for_song]


  def vote_for_song
      @song = Song.find(params[:id])
      current_user.vote_for(@song)
      respond_to do |format|
        format.js
      end
  end

  def vote_against_song
    @song = Song.find(params[:id])
    current_user.vote_against(@song)
    respond_to do |format|
      format.js
    end
  end


  # GET /Songs
  # GET /Songs.json
  def index
    @songs = Song.all
  end

  # GET /Songs/1
  # GET /Songs/1.json
  def show
   @comment = Comment.new(song: @song)
  end

  # GET /Songs/new
  def new
    @song = Song.new
  end

  # GET /Songs/1/edit
  def edit
  end

  # POST /Songs
  # POST /Songs.json
  def create
    @song = Song.new(song_params)

    respond_to do |format|
      if @song.save
        format.html { redirect_to @song, notice: 'Song was successfully created.' }
        format.json { render action: 'show', status: :created, location: @song }
      else
        format.html { render action: 'new' }
        format.json { render json: @song.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /Songs/1
  # PATCH/PUT /Songs/1.json
  def update
    respond_to do |format|
      if @song.update(song_params)
        format.html { redirect_to @song, notice: 'Song was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @song.errors, status: :unprocessable_entity }
      end
    end
  end

  # Song /Songs/1
  # Song /Songs/1.json
  def destroy
    @song.destroy
    respond_to do |format|
      format.html { redirect_to songs_url }
      format.json { head :no_content }
    end
  end

  private

    def set_song
       @song = Song.find(params[:id])
     end

     def song_params
       params.require(:song).permit(:title, :artist, :bio, :track, :user_id)
     end
  end

song.rb

class Song < ActiveRecord::Base

  acts_as_voteable

  belongs_to :user
  has_many :comments, :dependent => :destroy


has_attached_file :track,
                  :url  => "/assets/songs/:id/:style/:basename.:extension",
                  :path => ":rails_root/public/assets/songs/:id/:style/:basename.:extension"


  validates_attachment :track, :presence => true

  validates :title, length: { minimum: 10 }
  validates :bio, length: { maximum: 300 }



end

user.rb

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :songs
  has_many :comments

  acts_as_voter

end

vote.rb

class Vote < ActiveRecord::Base

  scope :for_voter, lambda { |*args| where(["voter_id = ? AND voter_type = ?", args.first.id, args.first.class.base_class.name]) }
  scope :for_voteable, lambda { |*args| where(["voteable_id = ? AND voteable_type = ?", args.first.id, args.first.class.base_class.name]) }
  scope :recent, lambda { |*args| where(["created_at > ?", (args.first || 2.weeks.ago)]) }
  scope :descending, lambda { order("created_at DESC") }

  belongs_to :voteable, :polymorphic => true
  belongs_to :voter, :polymorphic => true

  attr_accessible :vote, :voter, :voteable if ActiveRecord::VERSION::MAJOR < 4


  # Comment out the line below to allow multiple votes per user.
  validates_uniqueness_of :voteable_id, :scope => [:voteable_type, :voter_type, :voter_id]

end

routes.rb

Leap2::Application.routes.draw do

  resources :comments

  devise_for :users, controllers: {registrations: 'registrations'}
  resources :songs


  get '/contact', to: 'songs#contact'
  get '/faq', to: 'songs#faq'

  root to: 'songs#index'
  end

由于您需要:id参数,因此应该将其获取或放置,并且可以避免编写“ song_songs”

resources :songs do
  member do
    get :vote_for, :vote_against
  end
end

这得到的是poll_for_song_path(@song)和vote_against_song_path(@song)。 从技术上讲, put :vote_for会更正确,因为它不是幂等请求,但是您需要记住在网址末尾放置method: :put

编辑:要获得显示的投票数,请在页面中放置一个元素,例如

<span class="votes"><%= pluralize(song.votes.count, 'Vote') %></span>

在类似评论跨度之后。 另外,由于您远程调用了vote_for_song_path ,因此需要使用js更新页面,这意味着您需要能够在页面上找到具有歌曲投票数的位置。 这样做,将<li>替换为

<%= content_tag_for :li, song do %>
   [then put everything in your view that has to do with one song in the block]
<% end %>

这将生成类似<li id="song_21" class="song">... html,您可以在update_votes.js.erb模板中引用该html,

$("#song_<%= @song.id %> .votes").html("<%= pluralize(song.votes.count, "Vote") %>")

这会将javascript发送到您的视图以更新适当的元素; 您只需要指示控制器发送它即可。 我相信

format.js { render 'update_votes' }

在vote_for和vote_against操作中都可以做到。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM