Rails 4.评论中的NoMethodError#new

时间:2015-02-11 11:16:11

标签: ruby-on-rails ruby ruby-on-rails-3

建立电影评论网站,用户可以上传电影,但是当有人想通过点击写评论按钮查看电影时,我会在评论#new中收到错误NoMethodError。所以在我的代码中它转到_form reviews.html.erb

_form.reviews.html.erb

<%= form_for([@ movie,@ review])do | f | %> - 错误

<% if @review.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@review.errors.count, "error") %> prohibited this review from being saved:</h2>

      <ul>
      <% @review.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :rating %><br>
    <%= f.number_field :rating %>
  </div>
  <div class="field">
    <%= f.label :comment %><br>
    <%= f.text_area :comment %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

查看controller.rb

class ReviewsController < ApplicationController
  before_action :set_review, only: [:show, :edit, :update, :destroy]
  before_action :set_movie
  before_action :authenticate_user!


  respond_to :html

  def new
    @review = Review.new
    respond_with(@review)
  end

  def edit
  end

  def create
    @review = Review.new(review_params)
    @review.user_id = current_user.id
    @review.movie_id = @movie.id

    if @review.save
    redirect_to @movie
    else
    render 'new'
    end 

  end

  def update
    @review.update(review_params)
    respond_with(@review)
  end

  def destroy
    @review.destroy
    respond_with(@review)
  end

  private
    def set_review
      @review = Review.find(params[:id])
    end

    def set_movie
      @movies = Movie.find(params[:movie_id])
    end


    def review_params
      params.require(:review).permit(:rating, :comment)
    end
end

电影控制器

class MoviesController < ApplicationController
  before_action :set_movie, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, except: [:index, :show]


  def index
    @movies = Movie.all
  end


  def show
  end

  def new
    @movie = current_user.movies.build
  end

  # GET /movies/1/edit
  def edit
  end

  # POST /movies
  # POST /movies.json
  def create
    @movie = current_user.movies.build(movie_params)

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

  # PATCH/PUT /movies/1
  # PATCH/PUT /movies/1.json
  def update
    respond_to do |format|
      if @movie.update(movie_params)
        format.html { redirect_to @movie, notice: 'Movie was successfully updated.' }
        format.json { render :show, status: :ok, location: @movie }
      else
        format.html { render :edit }
        format.json { render json: @movie.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /movies/1
  # DELETE /movies/1.json
  def destroy
    @movie.destroy
    respond_to do |format|
      format.html { redirect_to movies_url, notice: 'Movie was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_movie
      @movie = Movie.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def movie_params
      params.require(:movie).permit(:title, :description, :movie_length, :director, :rating, :image)
    end
end

rake routes

new_movie_review GET    /movies/:movie_id/reviews/new(.:format)      reviews#new



NoMethodError in Reviews#new
Showing /Users/neilpatel/Desktop/Rails/movies/app/views/reviews/_form.html.erb where line #1 raised:

undefined method `reviews_path' for #<#<Class:0x007f92db41b548>:0x007f92dd52ff18>

Trace of template inclusion: app/views/reviews/new.html.erb

Rails.root: /Users/neilpatel/Desktop/Rails/movies

Application Trace | Framework Trace | Full Trace
app/views/reviews/_form.html.erb:1:in `_app_views_reviews__form_html_erb__1769795460297873272_70134360199660'
app/views/reviews/new.html.erb:3:in `_app_views_reviews_new_html_erb___894596083071563840_70134360230600'
app/controllers/reviews_controller.rb:11:in `new'

撰写评论按钮

<div class="panel panel-default">
  <div class="panel-body"></div>
    <div class="row">
      <div class="col-md-4">
        <%= image_tag @movie.image.url(:medium) %>
        <div class="table-responsive">
          <table class="table">
            <tbody></tbody>
            <tr>
              <td><strong>Title:</strong></td>
              <td><%= @movie.title %></td>
            </tr>
            <tr>
              <td><strong>Description:</strong></td>
              <td><%= @movie.description %></td>
            </tr>
            <tr>
              <td><strong>Movie Length:</strong></td>
              <td><%= @movie.movie_length %></td>
            </tr>
            <tr>
              <td><strong>Director:</strong></td>
              <td><%= @movie.director %></td>
            </tr>
            <tr>
              <td><strong>Rating:</strong></td>
              <td><%= @movie.rating %></td>
            </tr>
          </table>
          <%= link_to "Write a Review", new_movie_review_path(@movie) %>
        </div>
    </div>
</div>



<%= link_to 'Edit', edit_movie_path(@movie) %> |
<%= link_to 'Back', movies_path %>

配置路线

Rails.application.routes.draw do


  devise_for :users
    resources :movies do
     resources :reviews, except: [:show, :index]
  end

  root 'movies#index'
end

1 个答案:

答案 0 :(得分:1)

你有:

@movies = Movie.find(params[:movie_id])

在您的set_movie方法中。你应该:

@movie = Movie.find(params[:movie_id])