2016-12-13 6 views
0
feature "comment" do 
given(:user) do 
     build(:user) 
end 
background do 
    user1=create(:user) 
    user1.id=1 
    login_as(user1)  
end 
scenario "can create comment" do 
    @undertake=create(:undertake) 
    visit undertake_path(@undertake) 
    within("form#undertake-form-test") do 
     fill_in "content" , with: "heyheyhey" 
    end 
    click_button 'send-btn' 
    expect(page).to have_content 'heyheyhey' 
end 
end 

Это спецификация/features/comment_spec.rb. и это ниже - контроллеры/предпринять_controller.rb.rspec, undefined method `id 'for nil: NilClass

class UndertakesController < ApplicationController 
    def show 
    @undertake=Undertake.find_by(id: params[:id]) 
    @comment=current_user.comments.new 
end 

и нижеприведенные виды недвижимости/show.html.erb.

<p><%= @undertake.id %></p> 

и spec/заводы/предприниматели.rb.

FactoryGirl.define do 
    factory :undertake do 
    association :ask 
    association :user 
    id 1 
    user_id 2 
    ask_id 1 
    title "MyString" 
    content "MyText" 
    result false  
    end 
end 

routes.rb

resources :asks , except:[:edit, :update] do 
    resources :undertakes , only:[:create , :show , :destroy] , shallow: true do 
    resources :comments , only:[:create] 
    end 
end 

Теперь, почему у меня ошибка ActionView::Template::Error:undefined method id for nil:NilClass. Пожалуйста, помогите мне.

+0

, пожалуйста, отобразите файл 'routes.rb'. –

+0

Здесь можно найти маршруты.рб. Пожалуйста. –

+0

ресурсов: запрашивает, кроме: [: изменить,: обновить] сделать ресурсов: обязывает, только: [: создать,: показать,: уничтожить], неглубоко: true do ресурсов: только комментарии: [: create] end end –

ответ

2

Здесь происходит немало вещей, которые могут быть потенциальной причиной и которые являются очень унииоматическими, если не ошибаются.

Прежде всего имя undertake просто неправильно. Используйте название существительного Undertaking вместо имени модели.

Никогда не использовать find_by(id: params[:id]). Вместо этого используйте find(params[:id]), так как он поднимет ActiveRecord::RecordNotFoundError и отобразит страницу 404, если запись не будет найдена, вместо того, чтобы взорвать нулевую ошибку.

class UndertakingsController < ApplicationController 
    def show 
    @undertaking = Undertaking.find(params[:id]) 
    @comment = @undertaking.comments.new 
    end 
end 

Кроме того, вы должны создать комментарий от @undertaking - не передать идентификатор пользователя через форму, как это делает хлеб играть для malicous пользователь подделать.

Вместо назначить пользователя из сеанса при создании записей:

class CommentsController 
    # this assumes you are using Devise 
    before_action :authenticate_user! 
    def create 
    @comment = Comment.new(comment_params) do |c| 
     c.user = current_user 
    end 
    # ... 
    end 
end 

Это, как вы бы написать спецификацию идиоматически. Обратите внимание на использование memoized let помощников и тот факт, что вы NEVER назначить идентификаторы для записей. Это делается с помощью базы данных. Попытка сделать это вручную будет только испортить вещи.

require 'rails_helper' 
RSpec.describe 'Comments' do 
    let(:current_user) { create(:user) } 
    let(:undertaking) { create(:undertaking) } 

    background do 
    login_as(current_user) 
    end 

    scenario "can create a comment" do 
    visit undertaking_path(undertaking) 
    # Avoid using CSS selectors and instead write specs 
    # based on what the user sees as it makes specs brittle 
    within("form#undertake-form-test") do 
     fill_in "content" , with: "heyheyhey" 
     click_button 'Create comment' 
    end 
    expect(page).to have_content 'heyheyhey' 
    end 
end 

Использование let вместо @instance переменных. При написании функций, спецификаций запросов и контроллеров вам необходимо использовать FactoryGirl.create, а не build, поскольку более поздняя версия не вставляется в базу данных, и запись на самом деле не существует в вашем приложении rails.

Также ваше заводское определение плохо сломано. Вся идея фабрики заключается в том, что она должна создавать уникальные, достоверные записи. Никогда не устанавливайте идентификаторы на заводе.

FactoryGirl.define do 
    factory :undertaking do 
    title "MyString" 
    content "MyText" 
    user # just reference the factory if you REALLY need the association to exist 
    ask # just reference the factory if you REALLY need the association to exist 
    result false # this should probally be set through a DB default instead! 
    end 
end 
+0

Отличный совет! :) –

+0

Спасибо за советы! Я сделаю так! –