2012-06-22 30 views
7

我制作了部分表格用于创建微博,如Listing 10.33所示<%= render 'shared/error_messages', object: f.object %>并按照指示更新了相应的视图文件。然而,我不能让Rspec测试通过,因为我不断收到“未定义的局部变量或方法”对象“类...”任何想法?Hartl第10章未定义的局部变量或方法'object'

应用/视图/共享/ _micropost_form.html.erb

<%= form_for(@micropost) do |f| %> 
    <%= render 'shared/error_messages', object: f.object %> 
    <div class="field"> 
    <%= f.text_area :content, placeholder: "Compose new micropost..." %> 
    </div> 
    <%= f.submit "Post", class: "btn btn-large btn-primary" %> 
<% end %> 

应用/视图/共享/ _error_messages.html.erb

<% if object.errors.any? %> 
    <div id="error_explanation"> 
    <div class="alert alert-error"> 
     The form contains <%= pluralize(object.errors.count, "error") %>. 
    </div> 
    <ul> 
     <% object.errors.full_messages.each do |msg| %> 
     <li>* <%= msg %></li> 
     <% end %> 
    </ul> 
    </div> 
<% end %> 

应用/视图/用户/ new.html。 ERB

<% provide(:title, 'Sign up') %> 
<h1>Sign up</h1> 

<div class="row"> 
    <div class="span6 offset3"> 
    <%= form_for(@user) do |f| %> 
     <%= render 'shared/error_messages', object: f.object %> 
     <%= render 'fields', f: f %> 
     <%= f.submit "Create my account", class: "btn btn-large btn-primary" %> 
    <% end %> 
    </div> 
</div> 

应用/视图/用户/ 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', object: f.object %> 
     <%= render 'fields', f: f %> 
     <%= f.submit "Save changes", class: "btn btn-large btn-primary" %> 
    <% end %> 

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

认证规格

require 'spec_helper' 

describe "Authentication" do 

    subject { page } 

    describe "signin page" do 
    before { visit signin_path } 

    it { should have_selector('h1', text: 'Sign in') } 
    it { should have_selector('title', text: 'Sign in') } 
    end 

    describe "signin" do 
    before { visit signin_path } 

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

     it { should have_selector('title', text: 'Sign in') } 
     it { should have_error_message('Invalid') } 

     it { should_not have_link('Users', href: users_path) } 
     it { should_not have_link('Sign out', href: signout_path) } 

     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_selector('title', text: user.name) } 

     it { should have_link('Users', href: users_path) } 
     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 

    describe "authorization" do 

    describe "for non-signed-in users" do 
     let(:user) { FactoryGirl.create(:user) } 

     describe "in the Users controller" do 

     it { should_not have_link('Profile', href: user_path(user)) } 
     it { should_not have_link('Settings', href: edit_user_path(user)) } 

     describe "visiting the edit page" do 
      before { visit edit_user_path(user) } 
      it { should have_selector('title', text: 'Sign in') } 
     end 

     describe "submitting to the update action" do 
      before { put user_path(user) } 
      specify { response.should redirect_to(signin_path) } 
     end 

     describe "visiting the user index" do 
      before { visit users_path } 
      it { should have_selector('title', text: 'Sign in') } 
     end 
     end 

     describe "when attempting to visit a protected page" do 
     before do 
      visit edit_user_path(user) 
      fill_in "Email", with: user.email 
      fill_in "Password", with: user.password 
      click_button "Sign in" 
     end 

     describe "after signing in" do 

      it "should render the desired protected page" do 
      page.should have_selector('title', text: 'Edit user') 
      end 

     describe "when signing in again" do 
     before do 
      visit signin_path 
      fill_in "Email", with: user.email 
       fill_in "Password", with: user.password 
      click_button "Sign in" 
      end 

     it "should render the default (profile) page" do 
      page.should have_selector('title', text: user.name) 
     end 
      end 
     end 

     describe "in the Microposts controller" do 

     describe "submitting to the create action" do 
      before { post microposts_path } 
      specify { response.should redirect_to(signin_path) } 
     end 

     describe "submitting to the destroy action" do 
      before { delete micropost_path(FactoryGirl.create(:micropost)) } 
      specify { response.should redirect_to(signin_path) } 
     end 
     end 
    end 
    end 

    describe "as wrong user" do 
     let(:user) { FactoryGirl.create(:user) } 
     let(:wrong_user) { FactoryGirl.create(:user, email: "[email protected]") } 
     before { sign_in user } 

     describe "visiting Users#edit page" do 
     before { visit edit_user_path(wrong_user) } 
     it { should_not have_selector('title', text: full_title('Edit user')) } 
     end 

     describe "submitting a PUT request to the Users#update action" do 
     before { put user_path(wrong_user) } 
     specify { response.should redirect_to(root_path) } 
     end 
    end 

    describe "as non-admin user" do 
     let(:user) { FactoryGirl.create(:user) } 
     let(:non_admin) { FactoryGirl.create(:user) } 

     before { sign_in non_admin } 

     describe "submitting a DELETE request to the Users#destroy action" do 
     before { delete user_path(user) } 
     specify { response.should redirect_to(root_path) }   
     end 
    end 
    end 
end 

用户规格

require 'spec_helper' 

describe "User pages" do 

    subject { page } 

    describe "index" do 

    let(:user) { FactoryGirl.create(:user) } 

    before(:all) { 30.times { FactoryGirl.create(:user) } } 
    after(:all) { User.delete_all } 

    before(:each) do 
     sign_in user 
     visit users_path 
    end  

    it { should have_selector('title', text: 'All users') } 
    it { should have_selector('h1', text: 'All users') }  

    describe "pagination" do 

     it { should have_selector('div.pagination') } 

     it "should list each user" do 
     User.paginate(page: 1).each do |user| 
      page.should have_selector('li', text: user.name) 
     end 
     end 
    end 

    describe "delete links" do 

     it { should_not have_link('delete') } 

     describe "as an admin user" do 
     let(:admin) { FactoryGirl.create(:admin) } 
     before do 
      sign_in admin 
      visit users_path 
     end 

     it { should have_link('delete', href: user_path(User.first)) } 
     it "should be able to delete another user" do 
      expect { click_link('delete') }.to change(User, :count).by(-1) 
     end 
     it { should_not have_link('delete', href: user_path(admin)) } 
     end 
    end  
    end 

    describe "signup page" do 
    before { visit signup_path } 

    it { should have_selector('h1', text: 'Sign up') } 
    it { should have_selector('title', text: 'Sign up') } 
    end 

    describe "profile page" do 
    let(:user) { FactoryGirl.create(:user) } 
    let!(:m1) { FactoryGirl.create(:micropost, user: user, content: "Foo") } 
    let!(:m2) { FactoryGirl.create(:micropost, user: user, content: "Bar") } 

    before { visit user_path(user) } 

    it { should have_selector('h1', text: user.name) } 
    it { should have_selector('title', text: user.name) } 
    end 

    describe "microposts" do 
     it { should have_content(m1.content) } 
     it { should have_content(m2.content) } 
     it { should have_content(user.microposts.count) } 
    end 

    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_selector('title', text: 'Sign up') } 
     it { should have_content('error') } 
     end  
    end 

    describe "with valid information" do 
     before { valid_signup } 

     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('[email protected]') } 

     it { should have_selector('title', text: user.name) } 
     it { should have_success_message('Welcome') } 
    it { should have_link('Sign out') } 
     end 
    end 
    end 

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

    describe "page" do 
     it { should have_selector('h1', text: "Update your profile") } 
     it { should have_selector('title', text: "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 

    describe "with valid information" do 
     let(:new_name) { "New Name" } 
     let(:new_email) { "[email protected]" } 
     before do 
     fill_in "Name",    with: new_name 
     fill_in "Email",   with: new_email 
     fill_in "Password",   with: user.password 
     fill_in "Confirm Password", with: user.password 
     click_button "Save changes" 
     end 

     it { should have_selector('title', text: new_name) } 
     it { should have_success_message } 
     it { should have_link('Sign out', href: signout_path) } 
     specify { user.reload.name.should == new_name } 
     specify { user.reload.email.should == new_email } 
    end  
    end 
end 
+0

你能后的规范太好吗? – edralph

+0

@edr已更新,谢谢 – railser

+0

哪些规格失败?也许那些失败的是试图“<%= render”共享/ error_messages'%>',在那里你可能忘了包含'object:f.object'。 – cdesrosiers

回答

14

哇,现在我觉得自己像一个笨蛋......我在user fields partial

左侧有一个额外<%= render 'shared/error_messages' %>希望这将有助于任何有同样问题的人。

+0

它帮助了我!谢谢! – yaru

1

他应该更新教程,以提醒我们删除用户字段中的额外<%= render'shared/error_messages'%>,就像上面说的人一样。这是从以前的要求中遗留下来的。我有同样的问题。不要以为你是个笨蛋,很少有人会记得这一点。

8

本教程的当前版本,如2013年8月的,有一个警告:

(注:如果您执行清单9.50和清单从练习9.51第9.6节您的代码会有所不同? )

......但是和其他人一样,问这些问题我首先就错过了。所以再次,如果你在9.6节做了练习,那么不要编辑你当前的new.html.erb和edit.html.erb文件。您需要用<%= render 'shared/error_messages', object: f.object %>更新的唯一文件是_fields.html.erb。

0

对于任何仍在寻找的人,请查看app/views/users/_name_email_password_form.html.erb中的<%= render 'shared/error_messages'...行,如果您正在关注Hartl教程。

0

这是正确的代码

<% if error_messages.errors.any? %> 
    <div id="error_explanation"> 
    <div class="alert alert-danger"> 
     The form contains <%= pluralize(error_messages.errors.count,  "error") %>. 
    </div> 
    <ul> 
    <% error_messages.errors.full_messages.each do |msg| %> 
     <li><%= msg %></li> 
    <% end %> 
    </ul> 
    </div> 
<% end %> 

这是正确的形式做

相关问题