2016-12-13 17 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 

これはspec/features/comment_spec.rbです。以下はcontrollers/undertakes_controller.rbです。rspec、nilのための未定義メソッド `id ':NilClass

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

これはviews/undertakes/show.html.erbです。

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

およびspec/factories/undertakes.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

ここにroutes.rbがあります。お願いします。 リソース:コメントのみ:[:create] end: –

+0

リソース:asks、except:[:edit、:update] do リソース:実行する、:表示する、破棄する、 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からコメントを作成する必要があります - それはそれは偽装する悪質なユーザーのためにプレーチャイルズなりますよう、フォームを経由してユーザーIDを渡すことはありません。レコードを作成するときに

代わりにセッションからユーザーを割り当てる:

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 

これは、あなたが慣用的に仕様を記述します方法です。暗記されたletヘルパーの使用と、NEVERがレコードにIDを割り当てることに注意してください。これはデータベースによって行われます。手動でやろうとすると物事が乱れるだけです。

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 

代わり@instance変数の使用letを。フィーチャー、要求、コントローラーのスペックを書くときは、FactoryGirl.createではなくbuildを使用する必要があります。これは後でデータベースに挿入されず、レコードは実際にはあなたのレールアプリケーションには存在しません。

また、あなたの工場の定義はひどく壊れています。工場の考え方は、ユニークで有効なレコードを作成する必要があるということです。工場でIDを設定しないでください。

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

あなたのアドバイスありがとうございます!私はこのようにします! –

関連する問題