RoR, RSpec test failing after refactoring - ruby-on-rails-3

I'm new to programming and I'm having trouble figuring out an expected error in Hartl's Ruby on Rails 3 tutorial. After refactoring some layout pages, I'm getting a recurring error on what seems to be the {visit signup_path}.
Here's the partial refactoring I did:
_fields partial:
<%= 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 %>
On new.html.erb:
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(#user) do |f| %>
<%= render 'fields', f: f %>
<%= f.submit "Create my account", class: "btn btn-large btn-primary" %>
<% end %>
</div>
</div>
On 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 'fields', f: f %>
<%= f.submit "Save changes", class: "btn btn-large btn-primary" %>
<% end %>
<%= gravatar_for #user %>
change
</div>
And the testing spec that are causing 20 failures:
require 'spec_helper'
describe "User pages" do
subject { page }
describe "index" do
let(:user) { FactoryGirl.create(:user) }
before 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
before(:all) { 30.times { FactoryGirl.create(:user) } }
after(:all) { User.delete_all }
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: full_title('Sign up')) }
end
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
before { visit user_path(user) }
it { should have_selector('h1', text: user.name) }
it { should have_selector('title', text: user.name) }
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 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
describe "after saving the user" do
before { click_button submit }
let(:user) { User.find_by_email('user#example.com') }
it { should have_selector('title', text: user.name) }
it { should have_selector('div.alert.alert-success', text: 'Welcome') }
it { should have_link('Sign out') }
end
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
end
end
describe "edit" do
let(:user) { FactoryGirl.create(:user) }
before do
visit signup_path
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) { "new#example.com" }
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_selector('div.alert.alert-success') }
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
And the terminal output after running bundle exec rspec spec/
Failures:
1) User pages edit with valid information
Failure/Error: visit signup_path
ActionView::Template::Error:
/Users/ajorczak/rails_projects/sample_app/app/views/users/_fields.html.erb:14: syntax error, unexpected keyword_ensure, expecting $end
# <internal:prelude>:10:in `synchronize'
# ./app/views/users/new.html.erb:7:in `block in _app_views_users_new_html_erb__3426326572903275614_70133147147220'
# ./app/views/users/new.html.erb:6:in `_app_views_users_new_html_erb__3426326572903275614_70133147147220'
# ./spec/requests/user_pages_spec.rb:111:in `block (3 levels) in <top (required)>'
2) User pages edit with valid information
Failure/Error: visit signup_path
ActionView::Template::Error:
/Users/ajorczak/rails_projects/sample_app/app/views/users/_fields.html.erb:14: syntax error, unexpected keyword_ensure, expecting $end
# <internal:prelude>:10:in `synchronize'
# ./app/views/users/new.html.erb:7:in `block in _app_views_users_new_html_erb__3426326572903275614_70133147147220'
# ./app/views/users/new.html.erb:6:in `_app_views_users_new_html_erb__3426326572903275614_70133147147220'
# ./spec/requests/user_pages_spec.rb:111:in `block (3 levels) in <top (required)>'
etc. I'm not listing each error because I'm convinced (and Hartl says it's expected) it's the same error in the testing document. Can anyone give me some guidance?
Thank you for your time.

Not sure what I did to fix this, but it seemed to be a number of syntax errors across other areas. Found the solution though; There was a text change from 'Confirmation' to 'Confirm Password'. Thanks for those who took a gander. I'll mark resolved.

Related

Rails update in different controller

Hello im doing simple update..
logged_customer_controller.rb
class LoggedCustomerController < ApplicationController
before_filter :authorize
helper_method :current_customer
layout "frontend"
def current_customer
#current_customer ||= Customer.find(session[:customer_id]) if session[:customer_id]
end
def authorize
if session[:auth] != true
redirect_to login_path, :notice => "Not logged."
end
end
def show
end
def edit
end
def update
respond_to do |format|
if current_customer.update_attributes(params[:current_customer])
format.html { redirect_to view_path, notice: 'Customer was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: current_customer.errors, status: :unprocessable_entity }
end
end
end
end
routes.rb
match "view" => "logged_customer#show", :via => :get
match "edit" => "logged_customer#edit", :via => :get
match "edit" => "logged_customer#edit", :via => :put
edit.html.erb
<%= form_for current_customer, :url => url_for(:controller => 'logged_customer', :action => 'edit'), :html => { :class => 'form-horizontal' } do |f| %>
<% if current_customer.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(current_customer.errors.count, "error") %>.
</div>
<ul>
<% current_customer.errors.full_messages.each do |msg| %>
<li> <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
...
I can display localhost:3000/view where is edit button. At localhost:3000/edit the form is displayed with autofilled informations, everything looks good. When i click on submit button im redirected to same edit autofilled form but WITHOUT any error ? So i guess there is some mistake because updating failed and another mistake that it dont render errors. What im doing wrong ?
I have logged_customer_controller.rb because customer_controller.rb is for administration purposes and is under authorization.
at Development.log i have only (looks good)
Started PUT "/edit" for 127.0.0.1 at 2013-08-19 14:54:30 +0200
Processing by LoggedCustomerController#edit as HTML
Parameters: {...}
<Executing SQL ...>
Rendered logged_customer/edit.html.erb within layouts/frontend (67.0ms)
Completed 200 OK in 89ms (Views: 33.0ms | ActiveRecord: 56.0ms)
Well, on your form_for you say that the action is the edit one, when it should be update.
<%= form_for current_customer,
:url => url_for(:controller => 'logged_customer', :action => 'edit'),
:html => { :class => 'form-horizontal' } do |f| %>
This way, when you submit it would hit the edit action. Change this and you are good to go.
Also, change you route as #Mattherick said:
match "update" => "logged_customer#update", :via => :put
Change your routes (rails 3):
match "view" => "logged_customer#show", :via => :get
match "edit" => "logged_customer#edit", :via => :get
match "update" => "logged_customer#update", :via => :put
Change your routes (rails 4):
get "view" => "logged_customer#show"
get "edit" => "logged_customer#edit"
patch "update" => "logged_customer#update"
Change your form:
<%= form_for current_customer, :url => url_for(:controller => 'logged_customer', :action => 'update'), :method => "patch", :html => { :class => 'form-horizontal' } do |f| %>
<%= # your form fields %>
<% end %>

jquery ui dialog appears bottom of page

quite random behavior, I'm calling on a modal dialog to show a partial inside.
I'm working with simple_form + bootstrap and jquery-ui.
the button that calls the function has this code in the view:
<p><%= link_to 'New Boots', new_boot_path, :class => 'btn btn-primary pull-right', :remote => true, :id => 'new_boot_link' %></p>
in my views/boots/new the code is this:
<div id="content">
<%= render :partial => 'form' %>
</div>
and in views/boots/_form the following
<%= simple_form_for(#boot, :html => { :class => 'form-vertical' }, :remote => true) do |f| %>
<fieldset>
<%= f.input :number %>
<%= f.input :size, :collection => boot_size_options %>
<%= f.input :condition, :collection => boot_condition_options %>
<%= f.input :brand , :collection => boot_brand_options %>
</fieldset>
<div class="form-actions">
<%= f.button :submit, :class => 'btn btn-primary' %>
<%= submit_tag 'Reset', :type => :reset, :class => "btn btn-danger" %>
</div>
<% end %>
In application.js i have the following:
$(document).ready(function() {
$('#new_boot_link').click(function(e) {
var url = $(this).attr('href');
$('#modal').dialog({
title: "New Boots",
draggable: true,
resizable: false,
modal: true,
width:'auto',
open: function() {
return $(this).load(url + ' #content');}
});
});
});
So the modal works as it should, but it appears at the bottom of the screen, however if i close it and click on the button again, it shows right in the middle as it should have done in the first place.
Is it css? I think maybe not, as otherwise it would continue showing up constantly in the same place... so i dont know if is the way I'm calling the function?
Suggestions are welcome, this is quite an annoying glitch!
Sorry about previous mistakes.
Unfortunately I can't reproduce your problem in person. I suspect that this would help because it will convert the DIV and on call fill and display.
$(document).ready(function(){
var modal=$('#modal');
$('#new_boot_link').click(function(e) {
var url = $(this).attr('href');
modal.load(url + ' #content',function(){
modal.dialog("open");
});
});
modal.dialog({ autoOpen: false, title: "New Boots", draggable: true,
resizable: false, modal: true, width:'auto'});
});
Include: jQuery Center
Change to:
$(document).ready(function() {
$('#new_boot_link').click(function(e) {
var url = $(this).attr('href');
$('#modal').dialog({
title: "New Boots",
draggable: true,
resizable: false,
modal: true,
width:'auto',
open: function() {
return $(this).load(url + ' #content');}
});
}).center(false);
});
This set your dialog on middle-center of page.
If you have specific place you want show dialog force:
..}).css({position:"relative"}).css("left",null).css("top",null);
// Last too remove value of left and top. Trick with {left:null,top:null} does not work!

Problem with nested form sign-up process

After researching on SO, I found that I desire a sign-up process that goes:
User fills out form
User clicks 'Join'
User is created/logged in and redirected to fill out profile
Button clicked
User directed to profile
If I were to create a User and User's Profile in rails console it would look like this:
user = User.new
user.email = ""
user.password = ""
user.profile = Profile.new
user.profile.info = ""
user.profile.save
user.save
THE PROBLEM: I'm using a nested model form on the homepage to create the user and add that user's profile first/last name. What happens now is: The user clicks 'Join', they are redirected to /users, then redirected to /signup. That's where I'm stuck. It gives me the following error:
Action Controller: Exception caught
NoMethodError in ProfilesController#new
undefined method `profile=' for nil:NilClass
app/controllers/profiles_controller.rb:5:in `new'
I want /signup to be a form to fill in the profile but it's not working.
My code below...
Users#new.html.erb (homepage form):
<%= form_for(#user, :html => {:multipart => true, :id => 'homesign'}) do |f| %>
<%= f.hidden_field :id %>
<% if #user.errors.any? %>
<% end %>
<div>
<%= f.label :email %>
<%= f.text_field :email, :size => 38 %>
</div>
...
<%= f.fields_for :profile do |profile| %>
<%= profile.label :first_name %>
<%= profile.text_field :first_name, :size => 18 %>
...
<% end %>
<% end %>
Profiles#new.html.erb (signup form):
<%= form_for #profile, :html => { :multipart => true } do |f| %>
<table id="signupTable">
<tbody>
<tr>
<td class="label"><%= f.label :gender, "Gender:" %></td>
<td>
<fieldset>
<%= select(:gender, :gender_type, [['Female', 1], ['Male', 2], ['Rather not say', 3]], :class => 'optionText') %>
</fieldset>
</td>
</tr>
<tr>
<td class="label"><%= f.label :birthday, "Birthday:" %></td>
<td>
<fieldset>
<%= select_month(14, :prompt => 'Month', :field_name => 'Month', :id => 'Date.mon') %>
<%= select_day(32, :prompt => 'Day') %>
<%= select_year(0, {:prompt => "Year", :start_year => DateTime.now.year, :end_year => DateTime.now.year - 115}, {:field_name => 'Year', :id => 'Date.year'}) %>
</fieldset>
<% end %>
User.rb:
class User < ActiveRecord::Base
attr_accessor :password
has_one :profile, :dependent => :destroy
accepts_nested_attributes_for :profile
validates :email, :uniqueness => true,
:length => { :within => 5..50 },
:format => { :with => /^[^#][\w.-]+#[\w.-]+[.][a-z]{2,4}$/i }
validates :password, :confirmation => true,
:length => { :within => 4..20 },
:presence => true,
:if => :password_required?
end
Profile.rb:
class Profile < ActiveRecord::Base
belongs_to :user
accepts_nested_attributes_for :user
end
UsersController:
class UsersController < ApplicationController
before_filter :authenticate, :only => [:edit, :update]
def new
#user = User.new
#user.profile = Profile.new
if logged_in?
redirect_to current_user.profile
end
end
def index
#user = User.all
end
def create
#user = User.new(params[:user])
if #user.save
session[:user_id] = user.id
redirect_to new_user_profile_path(:user_id => #user), :notice => 'User successfully added.'
else
render :action => 'new'
end
end
end
ProfilesController:
class ProfilesController < ApplicationController
before_filter :authenticate, :only => [:edit, :update]
def new
#user.profile = Profile.new
end
def create
#profile = Profile.new(params[:profile])
if #profile.save
redirect_to profile_path(#profile), :notice => 'User successfully added.'
else
render :action => 'new'
end
end
def index
#profile = current_user.profile
end
end
SessionsController (create only):
class SessionsController < ApplicationController
def create
if user = User.authenticate(params[:email], params[:password])
session[:user_id] = user.id
redirect_to user.profile, :notice => "Logged in successfully"
else
flash.now[:alert] = "Invalid login/password. Try again!"
render :action => 'new'
end
end
end
Routes.rb:
match "/signup" => "profiles#new", :as => "signup"
post "/profiles/new" => "profiles#create"
match "skip/signup", :to => "info#signupskip"
match "skip/profiles/new", :to => "profiles#newskip"
get "/profiles/:id" => "profiles#show", :as => "profile"
get "profiles/new"
root :to => "users#new"

How to retrieve data via ajax request and display the result into the next tag?

I using jQuery and have the following code, it's a partial and I want to know how could I retrieve a specific data on the onchange method and display the result into the next tag. (inside the span tag)
NOTE: this select field are generated on-the-fly, so, I can have N id's.
<p class="fields">
<%= f.collection_select(:part_id, #parts, :id, :title, { :prompt => true } , { :onchange => "?" } ) %>
<span class='part_price'> _ _ _ _ </span>
<%= f.hidden_field :_destroy %>
<%= link_to_remove_fields "remove", f %>
</p>
Also I've created the method for this action (I don't know if this is right):
def retrieve_part_price
#price = Part.find(params[:id])
respond_to do |format|
format.html { redirect_to(items_path)}
format.json { render #price }
end
end
And put that on the routes.rb:
resources :items do
member do
get :update_part_price
end
end
Solved.
my partial:
<p class="fields">
<%= f.collection_select(:part_id, #parts, :id, :title, { :prompt => true } , { :onchange => "load_part_price_select(this.id, this.options[this.selectedIndex].value);" } ) %>
<%= f.label(:part_id, "Price: ") %>
<span class="price"></span>
<%= f.hidden_field :_destroy %>
<%= link_to_remove_fields "remove", f %>
</p>
application.js
function load_part_price_select(id, value) {
$('#' + id ).live('change',function() {
$.ajax({
url: '/parts/' + value + '/price',
type: 'get',
context: this,
dataType: 'script',
success: function(responseData) {
$(this).nextAll("span.price:first").html(responseData);
}
});
});
};
controller:
def price
#price = Part.find(params[:id])
respond_to do |format|
format.js { render :text => #price.price }
end
end

Ruby on rails 3 link_to controller and action

I know this is probably a pretty simple concept. I am trying to create a link to a controller and action. For example I have a link in my layout file to update a record when a link is clicked, so I need to be able to link to the controller and action. How would I accomplish this?
link_to "Label", :controller => :my_controller, :action => :index
See url_for.
Also with CSS:
<%= link_to "Purchase", { :controller => :transactions, :action => :purchase }, { class: "btn btn-primary btn-lg", style: "width: 100%;" } %>
If you want to pass params too then do
<%= link_to student.name, controller: "users", action: "show", id: student.id, partial: "profile" %>