2012-06-22 20 views
7

Hice el formulario parcial para crear microposts como se muestra en Listing 10.33 con <%= render 'shared/error_messages', object: f.object %> y actualicé los respectivos archivos de vistas como se indica. Sin embargo, no puedo hacer que las pruebas Rspec pasen ya que sigo obteniendo "variable local indefinida o método 'objeto' para Clase ..." ¿Alguna idea?Hartl Capítulo 10 Variable local no definida o método 'objeto'

app/views/compartido/_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 %> 

app/views/shared/_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 %> 

app/views/usuarios/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> 

app/views/usuarios/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> 

autenticación Spec

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 

Spec usuario

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

Se puede publicar la especificación también por favor? – edralph

+0

@edr actualizado, gracias – railser

+0

¿Qué especificaciones están fallando? Quizás los que están fallando son los que intentan '<% = renderizar 'shared/error_messages'%>', donde tal vez se olvidó de incluir 'object: f.object'. – cdesrosiers

Respuesta

14

Vaya, ahora me siento como una cabeza hueca ... Me dejó un extra <%= render 'shared/error_messages' %> en el user fields partial

Esperamos que esto ayudará alguien más que tuvo el mismo problema

+0

me ayudó! ¡Gracias! – yaru

1

Debería actualizar el Tutorial para recordarnos que eliminemos el <% adicional = renderizar 'shared/error_messages'%> en los campos de usuario parciales como la persona mencionada anteriormente. Esto quedó de un requisito anterior para ello. Yo tuve el mísmo problema. No pienses que eres un tonto, pocos lo recordarán.

8

La versión actual de la guía de aprendizaje, a partir de Ago de 2013, tiene una advertencia:

(Nota: El código será diferente si se ha implementado listado 9,50 y 9,51 listado de los ejercicios en la Sección 9.6 ...)

... pero como todos los demás hacían estas preguntas, me lo perdí al principio. De nuevo, si realizó ejercicios en la Sección 9.6, NO edite sus archivos new.html.erb y edit.html.erb actuales. El único archivo que necesita actualizar con <%= render 'shared/error_messages', object: f.object %> es _fields.html.erb.

0

Para cualquiera que todavía esté buscando, verifique la línea <%= render 'shared/error_messages'... en app/views/users/_name_email_password_form.html.erb si está siguiendo junto con el tutorial de Hartl.

0

este es el código correcto

<% 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 %> 

Ésta es la forma correcta de hacerlo

Cuestiones relacionadas