2015-07-28 1 views
5

Добрый день, людиМои тесты проходят. Но неопределенный метод `review 'для nil: NilClass при вызове страницы

Я пытаюсь создать приложение для рассмотрения табака, не для чего, кроме как узнать еще кое-что. Я пытался использовать то, что я узнал в книге Rails Tutorial, однако я продолжаю сталкиваться с кирпичными стенами и решетками, которые я не понимаю. Я могу нормально пережить неопределенный метод «что-то» для nil: 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 

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 

Светильники

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 %> 

Модели

review.rb

belongs_to :tobacco 

tobacco.rb

has_many :reviews 

user.rb

has_many :tobaccos, dependent: :destroy 
has_many :reviews, dependent: :destroy 

Контроллер reviews_controller.rb

def new 
@review = Review.new 
end 

Это то, что я есть для действия создать в контроллере, но я не могу скажите, есть ли у меня это правильно, потому что я пока не могу загрузить страницу. Любые предложения по созданию действия были бы весьма полезны, если бы я задал еще один вопрос, если у меня есть это неправильно, что, вероятно, у меня есть!

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 

Маршруты

resources :tobaccos do 
resources :reviews, except: [:show, :index] 
end 

show.html.erb

<%= link_to "Write a Review", new_tobacco_review_path(@tobacco) %> 

new.html.Еврорадио

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

Когда я получаю на страницу, чтобы написать рецензию, я получаю ошибку

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

undefined method `reviews' for nil:NilClass 

Это говорит мне, что линия 11

<%= form_for([@tobacco, @tobacco.reviews.build]) do |f| %> 

, но все, что я пытаюсь я получаю другая ошибка. Я знаю, что это ошибка новобранец, но я не вижу этого.

Заранее спасибо

Shaun

UPDATE

Я получил это работает и сохранение в базе данных в настоящее время, я сделал это, как этот В reviews_controller.rb новое и создать взгляд как этот

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 

В review_params являются

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

Это все выглядит правильно для меня, и это работает, поэтому я надеюсь, что все в порядке.

Что я застрял сейчас, редактирует обзор, относящийся к табаку. Это первый раз, когда я работал на вложенных маршрутах. Я просто посмотрел пару учебных пособий, но ничто не помогло мне это исправить. Я не знаю, как я могу передать эти ключи ...

На шоу странице я получил этот метод

<%= link_to "Edit", edit_tobacco_review_path(@tobacco, @review) %> 

В шоу tobaccos_controller.rb выглядит как этот

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

В reviews_controller.rb я это

def edit 
    @tobacco = Tobacco.find(params[:tobacco_id]) 
    @review = Review.find(params[:id]) 
end 

И ошибка я получаю это

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

Глядя на это, я должен что-то делать в шоу-шоу Tobaccos #, но я не могу думать, что.

Я почти дома и сух, вы видите, что я сделал неправильно? Спасибо :)

UPDATE НОМЕР ДВА 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 %> 

UPDATE НОМЕР 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" %> 

_fields.html.Еврорадио

<%= 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' %> 
+1

В вашем 'new' действия, вам нужно добавить' @tobacco = Tobacco.find (PARAMS [: tobacco_id]) ' – AbM

+0

Благодаря @Abm тот работает, но его не сохраняя в базе данных, im, угадывая свою строку 2 моего действия. Можете ли вы пролить свет на меня, пожалуйста? – Shaun

+0

У вас есть метод strong_params? Пожалуйста, опубликуйте его. – Pavan

ответ

2

ActionController :: UrlGenerationError в табаков # показать ни одного маршрута не соответствует {: действие => "Изменить",: контроллер => "отзывы",: ID => ноль,: tobacco_id => "8"} отсутствует необходимые клавиши: [: ID

Вы перебор @reviews в review, так

эта линия

<%= link_to "Edit", edit_tobacco_review_path(@tobacco, @review) %> 

должен быть

<%= link_to "Edit", edit_tobacco_review_path(@tobacco, review) %> 
Смежные вопросы