0

我正在阅读 Hartl 先生的教程并尝试准确地复制它,甚至有点使用他完整的 github 代码作为指南,但是在运行“bundle exec rspec spec/”之后我坚持以下内容:

失败:

  1) Authentication signin with valid information 
     Failure/Error: before { sign_in user }
     ActionView::MissingTemplate:
       Missing template sessions/create, application/create with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in:
         * "/home/nemo/rails_projects/sample_app/app/views"
     # ./spec/support/utilities.rb:19:in `sign_in'
     # ./spec/requests/authentication_pages_spec.rb:32:in `block (4 levels) in <top (required)>'

  2) Authentication signin with valid information 
     Failure/Error: before { sign_in user }
     ActionView::MissingTemplate:
       Missing template sessions/create, application/create with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in:
         * "/home/nemo/rails_projects/sample_app/app/views"
     # ./spec/support/utilities.rb:19:in `sign_in'
     # ./spec/requests/authentication_pages_spec.rb:32:in `block (4 levels) in <top (required)>'

  3) Authentication signin with valid information 
     Failure/Error: before { sign_in user }
     ActionView::MissingTemplate:
       Missing template sessions/create, application/create with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in:
         * "/home/nemo/rails_projects/sample_app/app/views"
     # ./spec/support/utilities.rb:19:in `sign_in'
     # ./spec/requests/authentication_pages_spec.rb:32:in `block (4 levels) in <top (required)>'

  4) Authentication signin with valid information 
     Failure/Error: before { sign_in user }
     ActionView::MissingTemplate:
       Missing template sessions/create, application/create with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in:
         * "/home/nemo/rails_projects/sample_app/app/views"
     # ./spec/support/utilities.rb:19:in `sign_in'
     # ./spec/requests/authentication_pages_spec.rb:32:in `block (4 levels) in <top (required)>'

  5) Authentication signin with valid information 
     Failure/Error: before { sign_in user }
     ActionView::MissingTemplate:
       Missing template sessions/create, application/create with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in:
         * "/home/nemo/rails_projects/sample_app/app/views"
     # ./spec/support/utilities.rb:19:in `sign_in'
     # ./spec/requests/authentication_pages_spec.rb:32:in `block (4 levels) in <top (required)>'

  6) Authentication signin with valid information followed by signout 
     Failure/Error: before { sign_in user }
     ActionView::MissingTemplate:
       Missing template sessions/create, application/create with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in:
         * "/home/nemo/rails_projects/sample_app/app/views"
     # ./spec/support/utilities.rb:19:in `sign_in'
     # ./spec/requests/authentication_pages_spec.rb:32:in `block (4 levels) in <top (required)>'

  7) User pages profile page signup with valid information after saving the user 
     Failure/Error: before { visit user_path(user) }
     AbstractController::ActionNotFound:
       The action 'index' could not be found for UsersController
     # ./spec/requests/user_pages_spec.rb:16:in `block (3 levels) in <top (required)>'

  8) User pages profile page signup with valid information after saving the user 
     Failure/Error: before { visit user_path(user) }
     AbstractController::ActionNotFound:
       The action 'index' could not be found for UsersController
     # ./spec/requests/user_pages_spec.rb:16:in `block (3 levels) in <top (required)>'

  9) User pages profile page signup with valid information after saving the user 
     Failure/Error: before { visit user_path(user) }
     AbstractController::ActionNotFound:
       The action 'index' could not be found for UsersController
     # ./spec/requests/user_pages_spec.rb:16:in `block (3 levels) in <top (required)>'

  10) User pages profile page with invalid information 
     Failure/Error: before { click_button "Save changes" }
     Capybara::ElementNotFound:
       Unable to find button "Save changes"
     # ./spec/requests/user_pages_spec.rb:76:in `block (4 levels) in <top (required)>'

  11) User pages profile page page 
     Failure/Error: it { should have_content("Update your profile") }
       expected #has_content?("Update your profile") to return true, got false
     # ./spec/requests/user_pages_spec.rb:70:in `block (4 levels) in <top (required)>'

  12) User pages profile page page 
     Failure/Error: it { should have_title("Edit user") }
       expected #has_title?("Edit user") to return true, got false
     # ./spec/requests/user_pages_spec.rb:71:in `block (4 levels) in <top (required)>'

  13) User pages profile page page 
     Failure/Error: it { should have_link('change', href: 'http://gravatar.com/emails') }
       expected #has_link?("change", {:href=>"http://gravatar.com/emails"}) to return true, got false
     # ./spec/requests/user_pages_spec.rb:72:in `block (4 levels) in <top (required)>'

Finished in 1.83 seconds
53 examples, 13 failures

规范/请求/authentication_pages_spec.rb:

require 'spec_helper'

describe "Authentication" do

  subject { page }

  describe "signin page" do
    before { visit signin_path }

    it { should have_content('Sign in') }
    it { should have_title('Sign in') }
  end

  describe "signin" do

    before { visit signin_path }

    describe "with invalid information" do
        before { click_button "Sign in" }

        it { should have_title('Sign in') }
        it { should have_selector('div.alert.alert-error', text: 'Invalid') }

        describe "after visiting another page" do
          before { click_link "Home" }
          it { should_not have_selector('div.alert.alert-error') }
        end
    end

    describe "with valid information" do
      let(:user) { FactoryGirl.create(:user) }
      before { sign_in user }

      it { should have_title(user.name) }
      it { should have_link('Profile',     href: user_path(user)) }
      it { should have_link('Settings',    href: edit_user_path(user)) }
      it { should have_link('Sign out',    href: signout_path) }
      it { should_not have_link('Sign in', href: signin_path) }

      describe "followed by signout" do
        before { click_link "Sign out" }
        it { should have_link('Sign in') }
      end
    end
  end
end

规范/请求/user_pages_spec.rb

require 'spec_helper'

describe "User pages" do

  subject { page }

  describe "signup page" do
    before { visit signup_path }

    it { should have_content('Sign up') }
    it { should have_title(full_title('Sign up')) }
  end

  describe "profile page" do
    let(:user) { FactoryGirl.create(:user) }
    before { visit user_path(user) }

    it { should have_content(user.name) }
    it { should have_title(user.name) }

  describe "signup" do

    before { visit signup_path }

    let(:submit) { "Create my account" }

    describe "with invalid information" do
      it "should not create a user" do
        expect { click_button submit }.not_to change(User, :count)
      end

      describe "after submission" do
        before { click_button submit }

        it { should have_title('Sign up') }
        it { should have_content('error') }
      end
    end

    describe "with valid information" do

      before do
        fill_in "Name", with: "Example User"
        fill_in "Email", with: "user@example.com"
        fill_in "Password", with: "foobar"
        fill_in "Confirmation", with: "foobar"
      end

      it "should create a user" do
        expect { click_button submit }.to change(User, :count).by(1)
      end

      describe "after saving the user" do
        before { click_button submit }
        let(:user) { User.find_by(email: 'user@example.com') }

        it { should have_link('Sign out') }
        it { should have_title(user.name) }
        it { should have_selector('div.alert.alert-success', text: 'Welcome') }
      end
    end
  end

    describe "edit" do
      let(:user) { FactoryGirl.create(:user) }
      before { visit edit_user_path(user) }
    end

    describe "page" do
      it { should have_content("Update your profile") }
      it { should have_title("Edit user") }
      it { should have_link('change', href: 'http://gravatar.com/emails') }
    end

    describe "with invalid information" do
      before { click_button "Save changes" }

      it { should have_content('error') }
    end
  end
end

应用程序/控制器/users_controller.rb

class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
  end

  def new
   @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      sign_in @user
      flash[:success] = "Welcome to the Sample App!"
      redirect_to @user
    else
      render 'new'
    end
  end

  def edit
    @user = User.find(params[:id])
  end

  def update
    @user = User.find(params[:id])
    if @user.update_attributes(user_params)
      # Handle a successful update.
    else
      render 'edit'
    end
  end

  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end
end

应用程序/视图/用户/edit.html.erb:

<% provide(:title, "Edit user") %>
<h1>Update your profile</h1>

<div class="row">
  <div class="span6 offset3">
    <%= form_for(@user) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= f.label :name %>
      <%= f.text_field :name %>

      <%= f.label :email %>
      <%= f.text_field :email %>

      <%= f.label :password %>
      <%= f.password_field :password %>

      <%= f.label :password_confirmation, "Confirm Password" %>
      <%= f.password_field :password_confirmation %>

      <%= f.submit "Save changes", class: "btn btn-large btn-primary" %>
    <% end %>

    <%= gravatar_for @user %>
    <a href="http://gravatar.com/emails">change</a>
  </div>
</div>

我在这方面是个新手,所以如果你想检查我的任何其他代码,请告诉我。

添加到帖子 spec/support/utilities.rb 中:

include ApplicationHelper

RSpec::Matchers.define :have_error_message do |message|
  match do |page|
    page.should have_selector('div.alert.alert-error', text: 'Invalid')
  end
end

def sign_in(user, options={})
  if options[:no_capybara]
    # Sign in when not using Capybara.
    remember_token = User.new_remember_token
    cookies[:remember_token] = remember_token
    user.update_attribute(:remember_token, User.encrypt(remember_token))
  else
    visit signin_path
    fill_in "Email",    with: user.email
    fill_in "Password", with: user.password
    click_button "Sign in"
  end
end

添加了 app/controllers/sessions_controller.rb

class SessionsController < ApplicationController

  def new
end

  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      # Sign the user in and redirect to the user's show page.
    else
      flash.now[:error] = 'Invalid email/password combination'
      render 'new'
    end
  end

  def destroy
    sign_out
    redirect_to root_url
  end
end

应用程序/视图/会话/new.html.erb

<% provide(:title, "Sign in") %>
<h1>Sign in</h1>

<div class="row">
  <div class="span6 offset3">
    <%= form_for(:session, url: sessions_path) do |f| %>

      <%= f.label :email %>
      <%= f.text_field :email %>

      <%= f.label :password %>
      <%= f.password_field :password %>

      <%= f.submit "Sign in", class: "btn btn-large btn-primary" %>
    <% end %>

    <p>New user? <%= link_to "Sign up now!", signup_path %></p>
  </div>
</div>

我将部分代码恢复为从以前的教程到 session_controller.rb 的以下摘录:

.
.
  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      sign_in user
      redirect_to user
    else
      flash.now[:error] = 'Invalid email/password combination'
      render 'new'
    end
  end
.
.

这次只导致了 7 个错误。

Failures:

  1) User pages profile page signup with valid information after saving the user 
     Failure/Error: before { visit user_path(user) }
     NoMethodError:
       undefined method `paginate' for #<Class:0xa6de278>
     # ./app/controllers/users_controller.rb:4:in `index'
     # ./spec/requests/user_pages_spec.rb:16:in `block (3 levels) in <top (required)>'

  2) User pages profile page signup with valid information after saving the user 
     Failure/Error: before { visit user_path(user) }
     NoMethodError:
       undefined method `paginate' for #<Class:0xa6de278>
     # ./app/controllers/users_controller.rb:4:in `index'
     # ./spec/requests/user_pages_spec.rb:16:in `block (3 levels) in <top (required)>'

  3) User pages profile page signup with valid information after saving the user 
     Failure/Error: before { visit user_path(user) }
     NoMethodError:
       undefined method `paginate' for #<Class:0xa6de278>
     # ./app/controllers/users_controller.rb:4:in `index'
     # ./spec/requests/user_pages_spec.rb:16:in `block (3 levels) in <top (required)>'

  4) User pages profile page with invalid information 
     Failure/Error: before { click_button "Save changes" }
     Capybara::ElementNotFound:
       Unable to find button "Save changes"
     # ./spec/requests/user_pages_spec.rb:76:in `block (4 levels) in <top (required)>'

  5) User pages profile page page 
     Failure/Error: it { should have_content("Update your profile") }
       expected #has_content?("Update your profile") to return true, got false
     # ./spec/requests/user_pages_spec.rb:70:in `block (4 levels) in <top (required)>'

  6) User pages profile page page 
     Failure/Error: it { should have_title("Edit user") }
       expected #has_title?("Edit user") to return true, got false
     # ./spec/requests/user_pages_spec.rb:71:in `block (4 levels) in <top (required)>'

  7) User pages profile page page 
     Failure/Error: it { should have_link('change', href: 'http://gravatar.com/emails') }
       expected #has_link?("change", {:href=>"http://gravatar.com/emails"}) to return true, got false
     # ./spec/requests/user_pages_spec.rb:72:in `block (4 levels) in <top (required)>'

Finished in 1.88 seconds
53 examples, 7 failures

Failed examples:

rspec ./spec/requests/user_pages_spec.rb:57 # User pages profile page signup with valid information after saving the user 
rspec ./spec/requests/user_pages_spec.rb:58 # User pages profile page signup with valid information after saving the user 
rspec ./spec/requests/user_pages_spec.rb:59 # User pages profile page signup with valid information after saving the user 
rspec ./spec/requests/user_pages_spec.rb:78 # User pages profile page with invalid information 
rspec ./spec/requests/user_pages_spec.rb:70 # User pages profile page page 
rspec ./spec/requests/user_pages_spec.rb:71 # User pages profile page page 
rspec ./spec/requests/user_pages_spec.rb:72 # User pages profile page page 
4

1 回答 1

0

看起来问题出在您的Sessions#create方法上:

  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      # Sign the user in and redirect to the user's show page.
    else
      flash.now[:error] = 'Invalid email/password combination'
      render 'new'
    end
  end

我怀疑你最终会在你有评论的地方结束,此时它“落入”Rails 标准控制器代码,然后查找create与此create控制器方法相对应的会话视图。

如果您查看 Hartl github 存储库中的相应代码,它的:

  def create
    user = User.authenticate(params[:session][:email],
                             params[:session][:password])
    if user.nil?
      flash.now[:error] = "Invalid email/password combination."
      @title = "Sign in"
      render 'new'
    else
      sign_in user
      redirect_back_or user
    end
  end

至于您是如何到达那里的,该sign_in user方法似乎成功地访问并通过您的 Sessionsnew控制器和查看代码。在submit您看来,将您带到 Sessions#create 点。

于 2013-09-28T01:48:08.667 回答