views:

292

answers:

2

OK, so I'm really new to Ruby on Rails. I'm using InstantRails, if that is going to make any difference.

Here is my problem- I am trying to validate some entries into a form. If I use the form without any validations, then it works fine. If I add the validations, it completely changes the application's behavior and does not work.

For example, if I enter data (without validations) the form button submits the data using the create method which redirects the user back to the index. (where the form is) A list of everything that has been entered into the form at one point or annother is also on the index, so the user can see that their most recent submission has been added. (a flash message is also on the page as well after a submission)

BUT, if I do the same thing, only have validations un-commented in the model, nothing is stored in the database and instead of being redirected to index, Rails tries to redirect the use to the create page, which does not exist.

Below are posted the pertinent parts of my controller, model and view, as well as the Rails logs for the 2 scenarios.

Controller

def index
 @page_subtitle = "Manage Members"
 @contacts      = Directory.find(:all)
end

def edit
 @page_subtitle = "Edit entries"
end

def create
 @contact       = Directory.new(params[:contact])
 if @contact.save
  flash[:notice] = 'Contact was successfully added.'
  redirect_to :action => "index"
 end
end

Model

class Directory < ActiveRecord::Base
validates_presence_of :fname, :lname, :number
validates_numericality_of :number
validates_uniqueness_of :number
validates_length_of :number, :within => 7..10, :message => "Please enter a telephone number that is 7 to 10 digits long. If you require a longer number, please contact support."
end

view

<b>Add a new member:</b>
<hr>
<% form_for :contact, :url => { :action => "create" } do |f| %>
<table>
<tr>
 <td><%= f.text_field :fname %></td>
 <td><%= f.text_field :lname %></td>
 <td><%= f.text_field :number %></td>
</tr>
<tr height="5px">
</tr>
<tr>
 <td><%= f.submit "Add Member" %></td>
</tr>
     </table>
     <% end %>
     <br>
     <b>Members currently in database:</b>
     <hr>
     <table width="100%">
         <% for contact in @contacts %>
         <tr>
          <td><%=h contact.fname %></td>
          <td><%=h contact.lname %></td>
          <td><%=h contact.number %></td>
         </tr>
         <% end %>
     </table>
<br>

Log (empty model, working application)

Processing DirectoriesController#create (for 127.0.0.1 at 2009-10-07 23:11:01) [POST]
Session ID: BAh7BzoMY3NyZl9pZCIlODkwZWVmNzgxYzdlZmUxYjdiNWRjNjZiMWYxNGMw%0AMDkiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%0Ac2h7AAY6CkB1c2VkewA%3D--043c05ff742c224f3bbc27db8bd8330b0b962740
Parameters: {"commit"=>"Add Member", "contact"=>  {"number"=>"9882345688", "lname"=>"Person", "fname"=>"Unique"}, "authenticity_token"=>"467d6a642f0171a166ee093ec05bdef86ba009ac", "action"=>"create", "controller"=>"directories"}
[4;36;1mDirectory Columns (0.003000)[0m   [0;1mSHOW FIELDS FROM `directories`[0m
[4;35;1mSQL (0.000000)[0m   [0mBEGIN[0m
[4;36;1mDirectory Create (0.001000)[0m   [0;1mINSERT INTO `directories`   (`updated_at`, `number`, `lname`, `fname`, `created_at`) VALUES('2009-10-07 23:11:01', '9882345688', 'Person', 'Unique', '2009-10-07 23:11:01')[0m
[4;35;1mSQL (0.034000)[0m   [0mCOMMIT[0m
Redirected to http://127.0.0.1:3000/directories
Completed in 0.05100 (19 reqs/sec) | DB: 0.03800 (74%) | 302 Found    [http://127.0.0.1/directories/create]

Log (validations in model, broken application)

Processing DirectoriesController#create (for 127.0.0.1 at 2009-10-07 23:08:29) [POST]
Session ID: BAh7BzoMY3NyZl9pZCIlODkwZWVmNzgxYzdlZmUxYjdiNWRjNjZiMWYxNGMw%0AMDkiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%0Ac2h7AAY6CkB1c2VkewA%3D--043c05ff742c224f3bbc27db8bd8330b0b962740
Parameters: {"commit"=>"Add Member", "contact"=>{"number"=>"8641234567", "lname"=>"Timms", "fname"=>"John"}, "authenticity_token"=>"467d6a642f0171a166ee093ec05bdef86ba009ac", "action"=>"create", "controller"=>"directories"}
[4;36;1mDirectory Columns (0.003000)[0m   [0;1mSHOW FIELDS FROM `directories`[0m
[4;35;1mSQL (0.001000)[0m   [0mBEGIN[0m
[4;36;1mDirectory Load (0.001000)[0m   [0;1mSELECT * FROM `directories` WHERE (directories.number = '8641234567') LIMIT 1[0m
[4;35;1mSQL (0.000000)[0m   [0mCOMMIT[0m
Rendering template within layouts/application
Rendering directories/create
Completed in 0.02000 (50 reqs/sec) | Rendering: 0.00400 (20%) | DB: 0.00500 (25%) | 200 OK [http://127.0.0.1/directories/create]

Thanks for any help you can give!

A: 

I can guess that validates_uniqueness_of fails, which means @contact.save returns false and since you haven't told Rails what template to use in that case, it is using default one, which has the same name as action.

vava
A: 

@contact.save is returning false because the validations are failing. Your create action doesn't explicitly say what to render in that case, so Rails is trying to render what it thinks you want, namely a template named after your action: create.html.erb.

The conventional thing to do is rerender the new template so that the user can fix the problems.

def create
  @contact = Directory.new(params[:contact])
  if @contact.save
    flash[:notice] = 'Contact was successfully added.'
    redirect_to :action => "index"
  else
    # validation failed, so give the user a chance to fix it
    render :action => "new"
  end
end
Baldu