我的测试正在通过.但是,在调用页面时,nil:NilClass的未定义方法`review'

Sha*_*aun 5 ruby-on-rails ruby-on-rails-4

大家下午好

我正在尝试建立一个烟草审查申请,除了学习更多的东西之外别无他法.我一直在努力建立在Rails教程书中学到的东西,但是我不断遇到砖墙和我不理解的陷阱.我通常可以为nil克服未定义的方法`'something':NilClass和我有的其他问题,但这个真的让我难过,因为我的测试通过了.

我的测试

review_test.rb

require 'test_helper'

class ReviewTest < ActiveSupport::TestCase

# Define a user for the test
def setup
@user = users(:shaun)
@review = @user.reviews.build( rating: 5, 
                               comment:"This is a super snus",
                               tobacco_id: 1)
end

# Test should be valid
test "should be valid" do
    assert @review.valid?
end

# Test the user id is present
test "user id should be present" do
    @review.user_id = nil
    assert_not @review.valid?
end

# Test the tobacco id is present
test "tobacco id should be present"  do 
    @review.tobacco_id = nil
    assert_not @review.valid?
end

# Rating should be present
test "rating should be present" do
    @review.rating = "   "
    assert_not @review.valid?
end

# Comment should be present
test "comment should be present" do 
    @review.comment = "    "
    assert_not @review.valid?
end

# Verify that the first review in the DB is the same as fixture review
test "order should be most recent first" do
    assert_equal reviews(:most_recent), Review.first
end

end
Run Code Online (Sandbox Code Playgroud)

user_test.rb

# Test that a review is destroyed when a user is destroyed
test "associated reviews should be destroyed" do 
@user.save
@user.reviews.create!( rating: 5,
                       comment: "I love this suns, it's so good!",
                       tobacco_id: 1)
assert_difference 'Review.count', -1 do 
    @user.destroy
end
end
Run Code Online (Sandbox Code Playgroud)

赛程

reviews.yml

one:
rating: 5
tobacco_id: 1
comment: "This is a super snus"
created_at: <%= 3.hours.ago %>

two:
rating: 5
tobacco_id: 1
comment: "This is the best snus in the world"
created_at: <%= 2.hours.ago %>

three:
rating: 5
tobacco_id: 1
comment: "I will always buy this snus"
created_at: <%= 1.hours.ago %>

 most_recent:
 rating: 5
 tobacco_id: 1
 comment: "I have a shed load of this snus, it's great!"
 created_at: <%= Time.zone.now %>
Run Code Online (Sandbox Code Playgroud)

楷模

review.rb

belongs_to :tobacco
Run Code Online (Sandbox Code Playgroud)

tobacco.rb

has_many :reviews
Run Code Online (Sandbox Code Playgroud)

user.rb

has_many :tobaccos, dependent: :destroy
has_many :reviews, dependent: :destroy
Run Code Online (Sandbox Code Playgroud)

控制器 reviews_controller.rb

def new
@review = Review.new
end
Run Code Online (Sandbox Code Playgroud)

这就是我对控制器中的创建操作所拥有的但我不知道我是否有这个正确,因为我还无法加载页面.任何关于创建行动的建议都会非常感激,如果我有这个错误,我可能会有另外一个问题!

def create
    @tobacco = Tobacco.find(params[:tobacco_id])
    @review = @tobacco.reviews.new(params[:review].permit(:tobacco_id, :comment))
    @review.user = User.find(current_user.id)
    @review.save
    redirect_to tobacco_path(@tobacco)
end
Run Code Online (Sandbox Code Playgroud)

路线

resources :tobaccos do 
resources :reviews, except: [:show, :index]
end
Run Code Online (Sandbox Code Playgroud)

show.html.erb

<%= link_to "Write a Review", new_tobacco_review_path(@tobacco) %>
Run Code Online (Sandbox Code Playgroud)

new.html.erb

<%= form_for([@tobacco, @tobacco.reviews.build]) do |f| %>
<%= render 'fields', f: f %>
<%= f.submit "Save Review", class: 'btn btn-primary' %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

当我到页面写评论时,我得到了错误

Showing C:/Sites/apps/review/app/views/reviews/new.html.erb where line #11 raised:

undefined method `reviews' for nil:NilClass
Run Code Online (Sandbox Code Playgroud)

它告诉我它是第11行

<%= form_for([@tobacco, @tobacco.reviews.build]) do |f| %>
Run Code Online (Sandbox Code Playgroud)

但无论我尝试什么,我都会遇到不同的错误.我知道这是一个新手的错误,但我看不到它.

提前致谢

肖恩

UPDATE

我已经把它工作并保存到数据库了,我这样做了在reviews_controller.rb中new和create看起来像这样

def new
    @tobacco = Tobacco.find(params[:tobacco_id])
end


def create

@tobacco = Tobacco.find(params[:tobacco_id])
@review = Review.new(review_params)
@review.user_id = current_user.id
@review.tobacco_id = @tobacco.id

if @review.save
  redirect_to @tobacco
else
  render 'new'
end
end
Run Code Online (Sandbox Code Playgroud)

review_params是

def review_params
    params.require(:review).permit(:rating, :comment, :tobacco_id)
end
Run Code Online (Sandbox Code Playgroud)

这一切看起来都对我,它的工作原理我希望一切都好.

我现在坚持的是编辑属于烟草的评论.这是我第一次使用嵌套路线.我只是看了几个教程,但没有什么能真正帮助我解决这个问题.我不知道怎么能通过这些钥匙......

在节目页面上我有这个

<%= link_to "Edit", edit_tobacco_review_path(@tobacco, @review) %>
Run Code Online (Sandbox Code Playgroud)

show方法tobaccos_controller.rb看起来像这样

def show
    @tobacco = Tobacco.find(params[:id])
    @reviews = Review.where(tobacco_id: @tobacco.id)
end
Run Code Online (Sandbox Code Playgroud)

在reviews_controller.rb中我就是这个

def edit
    @tobacco = Tobacco.find(params[:tobacco_id])
    @review  = Review.find(params[:id])
end
Run Code Online (Sandbox Code Playgroud)

而我得到的错误就是这个

ActionController::UrlGenerationError in Tobaccos#show
No route matches {:action=>"edit", :controller=>"reviews", :id=>nil, :tobacco_id=>"8"} missing required keys: [:id]
Run Code Online (Sandbox Code Playgroud)

看着这个我应该在Tobaccos#show action中做点什么,但我想不出来.

我几乎回家干了,你能看出我做错了什么吗?谢谢 :)

更新号码两个show.html.erb 这不是整个节目页面,但它是重要的部分

<% if @reviews.blank? %>
    <h3>No reviews yet! Would you like to be the first?</h3>
    <%= link_to "Write Review", new_tobacco_review_path(@tobacco), class: "btn btn-danger" %>
<% else %>
    <% @reviews.each do |review| %>
 <div class="reviews">
    <p><%= review.comment %></p>
    <p><%= review.user.name %></p>
    <%= link_to "Edit", edit_tobacco_review_path(@tobacco, @review) %>
</div>
   <% end %>
<%= link_to "Write Another Review", new_tobacco_review_path(@tobacco), class: "btn btn-danger" %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

更新号码3 edit.html.erb

<%= form_for([@tobacco, @tobacco.reviews.build]) do |f| %>
<%= render 'fields', f: f %>
<%= f.submit "Update Review", class: 'btn btn-primary' %>
<% end %>
<%= link_to "Back", tobacco_path(@tobacco), 
class: "btn btn-default btn-block margin-top-25" %>
Run Code Online (Sandbox Code Playgroud)

_fields.html.erb

<%= f.label  :rating %>
<%= f.select :rating, [['1', 1], 
                   ['2', 2], 
                   ['3', 3], 
                   ['4', 4], 
                   ['5', 5]
                  ] ,class: 'form-control' %>

<%= f.label :comment %>
<%= f.text_field :comment, class: 'form-control' %>
Run Code Online (Sandbox Code Playgroud)

Pav*_*van 2

Tobaccos#show 中的 ActionController::UrlGenerationError 没有路由匹配 {:action=>"edit", :controller=>"reviews", :id=>nil, :tobacco_id=>"8"} 缺少必需的键:[:id

你正在迭代,@reviews所以review

这条线

<%= link_to "Edit", edit_tobacco_review_path(@tobacco, @review) %>
Run Code Online (Sandbox Code Playgroud)

应该

<%= link_to "Edit", edit_tobacco_review_path(@tobacco, review) %>
Run Code Online (Sandbox Code Playgroud)