Rails控制器创建方法中的预处理不起作用

时间:2013-10-10 11:02:18

标签: ruby-on-rails ruby rspec

我正在关注Michael Hartl的教程,并尝试实现类似Twitter的回复功能,即。 " @ 122-john-smith :你好那里"应该是对用户 122 的回复。

我首先尝试使用before_filter过滤" @XX-AAA-AAA" 部分,但我决定先在同一个{{}尝试1}}行动。到目前为止,我已经得到了Micropost#create

MicropostController

这是我尝试通过的片段测试:

class MicropostsController < ApplicationController
    before_filter :signed_in_user, only: [:create, :destroy]
    before_filter :correct_user, only: [:destroy]
    #before_filter :reply_to_user, only: [:create]

    def index
    end

    def create
        @micropost=current_user.microposts.build(params[:micropost])
        #Rails.logger.info "hoooola"
        regex=/\A@(\d)+(\w|\-|\.)+/i
        message=@micropost.content.dup
        isResponse=message.match(regex)[0].match(/\d+/)[0]
        @micropost.response=isResponse
        if @micropost.save
            flash[:success]="Micropost created!"
            redirect_to root_path
        else
            @feed_items=[]
            render 'static_pages/home'
        end
    end

    def destroy
        @micropost.destroy
        redirect_to root_path
    end

    private

    def correct_user
        @micropost = current_user.microposts.find_by_id(params[:id])
        redirect_to root_path if @micropost.nil?
    end

    def reply_to_user
        regex=/\A@(\d)+(\w|\-|\.)+/i
        #I use [0] cause the output of match is a MatchData class with lots of bs
        mtch=params[:micropost][:content].match(regex)[0]
        #puts mtch
        #@micropost=current_user.microposts.build(params[:micropost])
        if mtch != nil
            user_id=mtch.match(/\d+/)[0]
            @replied_user=User.find(user_id)
            @micropost.response=user_id unless @replied_user.nil?
        end
    end
end

如果我运行这些测试,我会得到以下错误:

require 'spec_helper'

describe "MicropostPages" do
    subject { page }
    let(:user) { FactoryGirl.create(:user) }
    before { valid_signin user }
    describe "micropost creation" do
        before { visit root_path }
        describe "with invalid information" do
            it "should not create a micropost" do
                expect { click_button "Post" }.should_not change(Micropost,
                                                                                        :count)
            end
            describe "error messages" do
                before { click_button "Post" }
                it { should have_content('error') }
            end
        end
        describe "with valid information" do
            before { fill_in 'micropost_content', with: "Lorem ipsum" }
            it "should create a micropost" do
                expect { click_button "Post" }.should change(Micropost,
                                         :count).by(1)
            end
        end
    end
    ...

end

然而如果我修改了测试并在Failures: 1) MicropostPages micropost creation with invalid information should not create a micropost Failure/Error: expect { click_button "Post" }.should_not change(Micropost, :count) NoMethodError: undefined method `[]' for nil:NilClass # ./app/controllers/microposts_controller.rb:14:in `create' # (eval):2:in `click_button' # ./spec/requests/micropost_pages_spec.rb:11:in `block (5 levels) in <top (required)>' # ./spec/requests/micropost_pages_spec.rb:11:in `block (4 levels) in <top (required)>' 2) MicropostPages micropost creation with invalid information error messages Failure/Error: before { click_button "Post" } NoMethodError: undefined method `[]' for nil:NilClass # ./app/controllers/microposts_controller.rb:14:in `create' # (eval):2:in `click_button' # ./spec/requests/micropost_pages_spec.rb:14:in `block (5 levels) in <top (required)>' 操作中注释掉了所有 @XXX 过滤:

Micropost#create

测试通过正常,新的 def create @micropost=current_user.microposts.build(params[:micropost]) #Rails.logger.info "hoooola" #regex=/\A@(\d)+(\w|\-|\.)+/i #message=@micropost.content.dup #isResponse=message.match(regex)[0].match(/\d+/)[0] #@micropost.response=isResponse if @micropost.save flash[:success]="Micropost created!" redirect_to root_path else @feed_items=[] render 'static_pages/home' end end 不是Micropost对象。

似乎无法在这里找到解释。

1 个答案:

答案 0 :(得分:1)

错误来自这一行:

isResponse=message.match(regex)[0].match(/\d+/)[0]

检查两个匹配电话是否实际匹配正确。如果在您的字符串中找不到该模式,则会返回nil并在[0]上进行nil调用。只有这一行中有两个实例可能会发生这种情况。

尝试将其展开几行并检查匹配的返回值或扩展正则表达式以便一次性正确检查模式。