0

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

我首先尝试使用 a 过滤“@XXX-AAA-AAA”部分before_filter,但我决定先在相同的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的不是Nil对象。

这里似乎找不到解释。

4

1 回答 1

1

错误来自这一行:

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

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

尝试将其分散到多行并检查匹配项的返回值或扩展正则表达式以一次性正确检查模式。

于 2013-10-10T11:12:06.200 回答