rails validation before action - ruby-on-rails

Here's what happens in my app:
customer enters phone number
phone number is searched in customer model to see if it exists
if it does exist, go to the customer show page
if it does not exist, go to customer new page to create new customer
According to my understanding, model validations are for data that is entered/edited/deleted into the database.
However, how can we check (use the validation) before anything searches in the database? And if it is incorrect (example: using letters instead of digits for phone number), then would show the error.
I was implementing html form input options to prevent someone from inputting letters in the phone number input box like this:
<%= form_tag(new_customer_path, method: :get) do %>
<%= telephone_field_tag :phone, nil, placeholder: "Phone Number", required: true, pattern: "[0-9]{10}", title: "Number must be 10 digits", maxlength: "10", class: "input-lg" %>
<%= submit_tag "Enter", class: "btn btn-primary btn-lg" %>
<% end %>
However my form was getting big because I would then put the html form input box options on everything (phone, zip-code, email, ect.).
What is more proper "Rails" way? Using active record validations to show errors, or providing html form input options to validate the data beforehand? Or is it the combination of both (max secure? client side and before database)?
Model
class Customer < ActiveRecord::Base
validates_presence_of :first_name, :last_name, :phone, :email, :zip_code
validates_uniqueness_of :phone, :email
validates :phone, :zip_code, :numericality => {:only_integer => true}
validates_length_of :phone, is: 10
validates_length_of :zip_code, is: 5
end
Controller
def new
if #customer = Customer.find_by(phone: params[:phone])
flash[:success] = "Welcome back"
redirect_to #customer
else
#customer = Customer.new(phone: params[:phone])
flash.now[:warning] = "Customer not found, please sign up!"
end
end
error messages partial
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>">
×
<ul>
<li>
<p><%= value %></p>
</li>
</ul>
</div>
<% end %>

The rails validation is probably good enough but if you're worried about it you could add a javascript validation on the client side. There are several plugins you could use if you want to do form validations client side or you could write your own. This might be helpful: http://www.tutorialspoint.com/javascript/javascript_form_validations.htm

Just add front end validations with JavaScript and HTML. Your Rails validations looks fine.
Html: required attribute.
Jquery: Check out this link - http://jqueryvalidation.org/

Related

Custom validation message for uniqueness in rails 5 [duplicate]

Using Rails I'm trying to get an error message like "The song field can't be empty" on save. Doing the following:
validates_presence_of :song_rep_xyz, :message => "can't be empty"
... only displays "Song Rep XYW can't be empty", which is not good because the title of the field is not user friendly. How can I change the title of the field itself ? I could change the actual name of the field in the database, but I have multiple "song" fields and I do need to have specific field names.
I don't want to hack around rails' validation process and I feel there should be a way of fixing that.
Now, the accepted way to set the humanized names and custom error messages is to use locales.
# config/locales/en.yml
en:
activerecord:
attributes:
user:
email: "E-mail address"
errors:
models:
user:
attributes:
email:
blank: "is required"
Now the humanized name and the presence validation message for the "email" attribute have been changed.
Validation messages can be set for a specific model+attribute, model, attribute, or globally.
In your model:
validates_presence_of :address1, message: 'Put some address please'
In your view
<% m.errors.each do |attr, msg| %>
<%= msg %>
<% end %>
If you do instead
<%= attr %> <%= msg %>
you get this error message with the attribute name
address1 Put some address please
if you want to get the error message for one single attribute
<%= #model.errors[:address1] %>
Try this.
class User < ActiveRecord::Base
validate do |user|
user.errors.add_to_base("Country can't be blank") if user.country_iso.blank?
end
end
I found this here.
Update for Rails 3 to 6:
validate do |user|
user.errors.add(:base, "Country can't be blank") if user.country_iso.blank?
end
Here is another way to do it.
What you do is define a human_attribute_name method on the model class. The method is passed the column name as a string and returns the string to use in validation messages.
class User < ActiveRecord::Base
HUMANIZED_ATTRIBUTES = {
:email => "E-mail address"
}
def self.human_attribute_name(attr)
HUMANIZED_ATTRIBUTES[attr.to_sym] || super
end
end
The above code is from here
Yes, there's a way to do this without the plugin!
But it is not as clean and elegant as using the mentioned plugin. Here it is.
Assuming it's Rails 3 (I don't know if it's different in previous versions),
keep this in your model:
validates_presence_of :song_rep_xyz, :message => "can't be empty"
and in the view, instead of leaving
#instance.errors.full_messages
as it would be when we use the scaffold generator, put:
#instance.errors.first[1]
And you will get just the message you specified in the model, without the attribute name.
Explanation:
#returns an hash of messages, one element foreach field error, in this particular case would be just one element in the hash:
#instance.errors # => {:song_rep_xyz=>"can't be empty"}
#this returns the first element of the hash as an array like [:key,"value"]
#instance.errors.first # => [:song_rep_xyz, "can't be empty"]
#by doing the following, you are telling ruby to take just the second element of that array, which is the message.
#instance.errors.first[1]
So far we are just displaying only one message, always for the first error. If you wanna display all errors you can loop in the hash and show the values.
Hope that helped.
Rails3 Code with fully localized messages:
In the model user.rb define the validation
validates :email, :presence => true
In config/locales/en.yml
en:
activerecord:
models:
user: "Customer"
attributes:
user:
email: "Email address"
errors:
models:
user:
attributes:
email:
blank: "cannot be empty"
In the custom validation method use:
errors.add(:base, "Custom error message")
as add_to_base has been deprecated.
errors.add_to_base("Custom error message")
Related to the accepted answer and another answer down the list:
I'm confirming that nanamkim's fork of custom-err-msg works with Rails 5, and with the locale setup.
You just need to start the locale message with a caret and it shouldn't display the attribute name in the message.
A model defined as:
class Item < ApplicationRecord
validates :name, presence: true
end
with the following en.yml:
en:
activerecord:
errors:
models:
item:
attributes:
name:
blank: "^You can't create an item without a name."
item.errors.full_messages will display:
You can't create an item without a name
instead of the usual Name You can't create an item without a name
One solution might be to change the i18n default error format:
en:
errors:
format: "%{message}"
Default is format: %{attribute} %{message}
I recommend installing the custom_error_message gem (or as a plugin) originally written by David Easley
It lets you do stuff like:
validates_presence_of :non_friendly_field_name, :message => "^Friendly field name is blank"
Here is another way:
If you use this template:
<% if #thing.errors.any? %>
<ul>
<% #thing.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
You can write you own custom message like this:
class Thing < ActiveRecord::Base
validate :custom_validation_method_with_message
def custom_validation_method_with_message
if some_model_attribute.blank?
errors.add(:_, "My custom message")
end
end
This way, because of the underscore, the full message becomes " My custom message", but the extra space in the beginning is unnoticeable. If you really don't want that extra space at the beginning just add the .lstrip method.
<% if #thing.errors.any? %>
<ul>
<% #thing.errors.full_messages.each do |message| %>
<li><%= message.lstrip %></li>
<% end %>
</ul>
<% end %>
The String.lstrip method will get rid of the extra space created by ':_' and will leave any other error messages unchanged.
Or even better, use the first word of your custom message as the key:
def custom_validation_method_with_message
if some_model_attribute.blank?
errors.add(:my, "custom message")
end
end
Now the full message will be "My custom message" with no extra space.
If you want the full message to start with a word capitalized like "URL can't be blank" it cannot be done. Instead try adding some other word as the key:
def custom_validation_method_with_message
if some_model_attribute.blank?
errors.add(:the, "URL can't be blank")
end
end
Now the full message will be "The URL can't be blank"
Just do it the normal way:
validates_presence_of :email, :message => "Email is required."
But display it like this instead
<% if #user.errors.any? %>
<% #user.errors.messages.each do |message| %>
<div class="message"><%= message.last.last.html_safe %></div>
<% end %>
<% end %>
Returns
"Email is required."
The localization method is definitely the "proper" way to do this, but if you're doing a little, non-global project and want to just get going fast - this is definitely easier than file hopping.
I like it for the ability to put the field name somewhere other than the beginning of the string:
validates_uniqueness_of :email, :message => "There is already an account with that email."
Here is my code that can be useful for you in case you still need it:
My model:
validates :director, acceptance: {message: "^Please confirm that you are a director of the company."}, on: :create, if: :is_director?
Then I have created a helper to show messages:
module ErrorHelper
def error_messages!
return "" unless error_messages?
messages = resource.errors.full_messages.map { |msg|
if msg.present? && !msg.index("^").nil?
content_tag(:p, msg.slice((msg.index("^")+1)..-1))
else
content_tag(:p, msg)
end
}.join
html = <<-HTML
<div class="general-error alert show">
#{messages}
</div>
HTML
html.html_safe
end
def error_messages?
!resource.errors.empty?
end
end
If you want to list them all in a nice list but without using the cruddy non human friendly name, you can do this...
object.errors.each do |attr,message|
puts "<li>"+message+"</li>"
end
In your view
object.errors.each do |attr,msg|
if msg.is_a? String
if attr == :base
content_tag :li, msg
elsif msg[0] == "^"
content_tag :li, msg[1..-1]
else
content_tag :li, "#{object.class.human_attribute_name(attr)} #{msg}"
end
end
end
When you want to override the error message without the attribute name, simply prepend the message with ^ like so:
validates :last_name,
uniqueness: {
scope: [:first_name, :course_id, :user_id],
case_sensitive: false,
message: "^This student has already been registered."
}
I tried following, worked for me :)
1 job.rb
class Job < ApplicationRecord
validates :description, presence: true
validates :title,
:presence => true,
:length => { :minimum => 5, :message => "Must be at least 5 characters"}
end
2 jobs_controller.rb
def create
#job = Job.create(job_params)
if #job.valid?
redirect_to jobs_path
else
render new_job_path
end
end
3 _form.html.erb
<%= form_for #job do |f| %>
<% if #job.errors.any? %>
<h2>Errors</h2>
<ul>
<% #job.errors.full_messages.each do |message|%>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
<div>
<%= f.label :title %>
<%= f.text_field :title %>
</div>
<div>
<%= f.label :description %>
<%= f.text_area :description, size: '60x6' %>
</div>
<div>
<%= f.submit %>
</div>
<% end %>
A unique approach I haven't seen anyone mention!
The only way I was able to get all the customisation I wanted was to use an after_validation callback to allow me to manipulate the error message.
Allow the validation message to be created as normal, you don't need to try and change it in the validation helper.
create an after_validation callback that will replace that validation message in the back-end before it gets to the view.
In the after_validation method you can do anything you want with the validation message, just like a normal string! You can even use dynamic values and insert them into the validation message.
#this could be any validation
validates_presence_of :song_rep_xyz, :message => "whatever you want - who cares - we will replace you later"
after_validation :replace_validation_message
def replace_validation_message
custom_value = #any value you would like
errors.messages[:name_of_the_attribute] = ["^This is the replacement message where
you can now add your own dynamic values!!! #{custom_value}"]
end
The after_validation method will have far greater scope than the built in rails validation helper, so you will be able to access the object you are validating like you are trying to do with object.file_name. Which does not work in the validation helper where you are trying to call it.
Note: we use the ^ to get rid of the attribute name at the beginning of the validation as #Rystraum pointed out referencing this gem
graywh's answer is the best if it actually locales different in displaying the field name. In the case of a dynamic field name (based on other fields to display), I would do something like this
<% object.errors.each do |attr, msg| %>
<li>
<% case attr.to_sym %>
<% when :song_rep_xyz %>
<%= #display error how you want here %>
<% else %>
<%= object.errors.full_message(attr, msg) %>
<% end %>
</li>
<% end %>
the full_message method on the else is what rails use inside of full_messages method, so it will give out the normal Rails errors for other cases (Rails 3.2 and up)
Upgraded #Federico answer to be universal for all field errors.
In your controller.rb:
flash[:alert] = #model.errors.messages.values
# [["field1_err1", "field1_err2"], ["field2_err1"], ["field3_err1"]]
messages method "returns a Hash of attributes with an array of their error messages" as in rails docs.
Then, to display those errors in a form:
<% flash.each do |type, type_arr| %>
<% type_arr.each do |msg| %>
<ul>
<li>
<%= msg.to_sentence %>
</li>
</ul>
<% end %>
<% end %>

Moving error conditionals out of the view. -Rails

I have a form that has a text field for name, it has a presence validation on it. When a user forgets to input the name the text field turns red this is all fine but I'd like to clean up my view a little bit but I'm not sure how? Maybe a helper? Maybe a method? I'm a bit new to rails and I'm looking for some advice on this problem. Here is my code for the view.
VIEW
<% if f.object.errors[:name].present? %>
<%= f.text_field :name, :class => 'alert' %>
<div class="validation">
<% f.object.errors[:name].each do |error| %>
<%= error %>
<% end %>
</div>
<% else %>
<%= f.text_field :name %>
<% end %>
It's a pretty standard if else statment but I'd think its a little too ugly for the view.
You can achieve a similar result using your model validation. If you require a presence validation on a model, then it will tell the user the field cannot be blank. This would allow you to tell the user they cannot leave a form field blank without manually coding this in your views.
Example: Post Model - app/models/post.rb
class Post < ActiveRecord::Base
validates :title, :presence => true
validates :body, :presence => true
end
If the user now attempts to submit the form with either Title or Body empty then they will be asked to resubmit the form, with a little tool tip saying "Please fill out this field".
No logic is needed in the view to achieve this, simply validate presence in your model.

trying to view error messages in rails

class Person < ActiveRecord::Base
before_save {self.email = email.downcase}
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { maximum: 6}
end
I am really new to Ruby. I was learning from Michael Hartl's tutorial. When creating signup form (tutorial 7) I got stuck in displaying error messages ( like if we leave any field blank there should be notifications in red right?).I added error_messages.html.erb file. Rendered it in form. Still there are no messages.
What I guessed is, I am using :user in my form creation to save the user. where as it should be #user. So that it can create user?
but when I did so, It gave me anonymous error of user_path. I searched for that display of error messages on stack but was not able to find.
Kindly help me with it. I am stuck since very long.
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(:person) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation %>
<%= f.submit "Create my account", class: "btn btn-primary" %>
<% end %>
</div>
</div>
<% if #person.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
the form contains <%= #person.errors.count %> errors.
</div>
<ul>
<%= #person.errors.full_messages.each do |msg| %>
<li> <%= msg %> </li>
<% end %>
</ul>
</div>
<% end %>
class PersonsController < ApplicationController
def show
#person = Person.find(params[:id])
end
def new
#person = Person.new
end
def create
#person = Person.new(user_params)
if #person.save
else
render new
end
end
private
def user_params
params.require(:person).permit(:name, :email, :password, :password_confirmation)
end
end
Rails.application.routes.draw do
get 'persons/show'
root 'staticpages#home'
get 'help' => 'staticpages#help'
get 'about' => 'staticpages#about'
get 'signUp' => 'persons#new'
resource :person
resources :persons
end
// error when i use #user in form. Instead of :user
NoMethodError in PersonsController#new
undefined method `users_path' for #<#<Class:0x007fdb68c0ee78>:0x007fdb68c0e428>
Extracted source (around line #220):
if options.empty?
recipient.send(method, *args)
else
recipient.send(method, *args, options)
end
Based on the code I have seen in the GitHub repo, the major problem I identified was with the naming. There was a large level of conflict in the name person in that its plural is people and not persons.
Rails has its way of pluralizing model names so User has a UsersController and Person has PeopleController and so forth.
Following are the changes required to fix the problems with sign up:
You need to change your controller name from PersonsController to PeopleController (both class name and file name).
In the PeopleController, the strong parameters method Person_params needs to change to lowercase (person_params). Otherwise, Rails would treat it as a constant name and start hunting for it and wouldn't find it.
You'll have to update the persons folder name in the app/views folder to people for the same reason specified above.
In your routes.rb file, there are two changes required. Change resource :person to resources :people and get 'signUp' should match to 'people#new' instead of 'persons#new' (now you know why).
Create a new file in app/views/people called create.html.erb. Once a person is created, Rails automatically renders this file and will throw an exception if it does not find it.
In the file app/views/people/new.html.erb, change the variable passed to form_for from :person to #person. #person is an instance variable initialized when that page is visited (see the new action in the PeopleController).
I'm not sure if this change will be needed, but if you face any errors after making the above changes, add gem 'therubyracer' to your Gemfile and run bundle install. This will install the rubyracer gem which I believe will be required for this version of Rails.
You should really familiarize yourself with the fundamentals of the framework and the Ruby language. It'll help you identify and debug these issues yourself. But I figured since you're new to it, this lengthy answer might help get rid of your frustration :).
You have used the User model in multiple places. The actual model is called Person. Switch to this model name in all the controllers and the model class.
And I'd also like to make a suggestion. When studying the tutorial, please do not blindly copy and paste snippets. Understand what their purpose is and write them in your files on your own.

Add a contact form to Hartl's tutorial

I'm learning Rails by following Hartl's tutorial and making my own adjustments to it. Now, I would like to extent it and add a contact form that sends an email message. Such is not included in the tutorial, but by the end of chapter 10 we're learned to use the mailer method and we've configured SendGrid on Heroku.
I already have the view set up in the routes and think it would require the following additional steps:
1) Terminal. rails generate mailer ContactForm
2) In app/mailers/contactform.rb:
def send_contactform_email(visitor)
#visitor = visitor
mail( :to => myemail#example.com, :from => visitor.email, :subject => 'Contact form' )
end
3) app/views/contactform_mailer/ (the view for the mail message) for example:
<h1>Website contact form</h1>
<p>On <$= ... %> <%= "#{#visitor.name} (#{#visitor.email} sent the following message:" %></p>
<p><%= #visitor.message %></p>
4) app\controllers\static_pages_controller (or another location?)
# Sends contact form email.
def send_contact_form_email
ContactFormMailer.send_contactform_email(visitor).deliver_now
redirect_to contact_path, notice: 'Message sent'
end
5) app\views\static_pages\contact.html.erb (I'm not sure about the first line, should I also do something in the routes.rb? My guess is this first line will have to tell to execute the method in step 4, which is not going to work the way it is now.)
<%= form_for(:static_pages, url: contactform_path) do |f| %>
<i class="pt-row-icon glyphicon glyphicon-user"></i> <%= f.label :name %>
<%= f.text_field :name, placeholder: 'Name', class: 'form-control' %>
<i class="pt-row-icon glyphicon glyphicon-envelope"></i> <%= f.label :email %>
<%= f.email_field :email, placeholder: 'Email', class: 'form-control' %>
<i class="pt-row-icon glyphicon glyphicon-envelope"></i> <%= f.label :message %>
<%= f.text_area :message, placeholder: 'Your message…', class: 'form-control' %>
<%= f.submit "Send", class: "btn btn-primary" %>
<% end %>
I don't think this is 100% correct yet, particularly the bold sections. What are your thoughts?
UPDATE, VERSION 2: I've tried to make the updates as suggested by Ven and now have the code below. The idea as I understand it is that
the controller in def contact sets the #message variable.
the form_for knows it should fill this variable with params[:message].
the controller adopts the values from the form_for and passes them to the mailer.
the mailer uses the mailer view to design the message to be sent.
the mailer sends it back to the controller that send the message.
1) App/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController
before_action :valid_email?, only: [:send_message_email]
# Shows the contact form page
def contact
#message = message(message_params)
end
# Sends the message.
def send_message_email
#message = message(message_params)
if #message.valid?
MessageMailer.new_message(#message).deliver_now
redirect_to contact_path, notice: "Your messages has been sent."
else
flash[:alert] = "An error occurred while delivering this message."
render :new
end
end
private
def message_params
params.require(:message).require(:name, :email, :content)
end
def valid_email?(email)
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
email.present? && (email =~ VALID_EMAIL_REGEX)
end
end
2) Contact form in app\views\static_pages\contact.html.erb:
<%= form_for(message: params[:message], url: contact_path) do |f| %>
<%= f.label :name %> <%= f.text_field :name, placeholder: 'Name', class: 'form-control' %>
<%= f.label :email %> <%= f.email_field :email, placeholder: 'Email', class: 'form-control' %>
<%= f.label :content %> <%= f.text_area :content, placeholder: 'Your message…', class: 'form-control' %>
<%= f.submit "Send", class: "btn btn-primary" %>
<% end %>
3) Routes.rb
get 'contact' => 'static_pages#contact', as: 'contact'
post 'contact' => 'static_pages#send_message_email'
4) App/views/message_mailer.text.erb (and html.erb)
<%= #message[:name] %> <%= #message[:email] %> wrote:
<%= #message[:content] %>
5) App/mailers/message_mailer.rb
class MessageMailer < ApplicationMailer
default to: "myemail#example.com>"
def new_message(message)
#message = message
mail to: "myemail#example.com"
mail from: #message[:email]
mail subject: "Message from #{message[:name]}"
end
end
Now when I try to visit the contact form on the server, I get the error message: param is missing or the value is empty: message. It refers to the params.require(:message).require(:name, :email, :content) line. Not sure what I'm doing wrong. Changing it to params.require(:message).permit(:name, :email, :content) makes no difference.
4) app\controllers\static_pages_controller (or another location?)
This seems to be correct, if this is the github repo for said app.
def send_contact_form_email
You controller has an issue: this action will try to send the email, not matter if it's used in POST or GET. You should use two different actions, one for displaying the view (using GET), and one for sending the email (using the mailer class you created). (at this point, you might want to create another controller)
ContactFormMailer.send_contactform_email(visitor).deliver_now
Then, moving on: what you pass to your mailer is "visitor". There's no such variable.
You probably want to access something out of the params hash (which contains parameters for GET and POST requests), and use the same key as your form (form_for(:visitor ... => params[:visitor] (so you want to change that :static_pages)).
<p>On <$= ... %> <%= "#{#visitor.name} (#{#visitor.email} sent the following message:" %></p>
As this returns an object, and not a hash, #visitor.email needs to be #visitor[:email] inside the mailer.
One last thing: simply using params[:visitor] will mean people could leave the field blanks. You might want to look into strong parameters, that were added in Rails 4 (the book seems somewhat outdated?).
And lastly, you need to add routes to be able to reach these actions (one for the GET request - display the view - and one for the POST request - to submit the form).
PS:
mail( :to => myemail#example.com, :from => visitor.email, :subject => 'Contact form' )
Warning: here, you forgot to quote the email address. Also, you swapped the to/from parameters. You want to send TO your visitor email, not from it.
EDIT
params.require(:message).require(:name, :email, :content)
This will require said keys, but AFAIK on the same "level" as :message - the top one. You want to use permit:
params.require(:message) # require "namespace"
.permit(:name, :email, :content) # permit keys
#message = message(message_params)
Where is the message function defined?
mail to: "myemail#example.com"
mail from: #message[:email]
mail subject: "Message from #{message[:name]}"
This sends 3 different emails, since you called the mail function 3 times.

Rails: 'Email has already been taken' for every email I enter

Update:
Checking the console, a lot of the users are actually going into the database, even when this error message appears!
Even weirder, you will notice that I have a redirect to root_path on a successful save to the database. it never goes there. This is the log. If it saves, it sometimes goes to the show action but there's actually a moment when the browser appears to get stuck, everything blanks it and I have to click in the address field to push it through to show.index.html.
Redirected to http://localhost:3000root_path
Completed 302 Found in 34ms
[2012-01-08 18:08:27] ERROR URI::InvalidURIError: the scheme http does not accept registry part: localhost:3000root_path (or bad hostname?)
/Users/mel/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/uri/generic.rb:746:in `rescue in merge'
/Users/me/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/uri/generic.rb:743:in `merge'
/Users/me/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpresponse.rb:163:in `setup_header'
/Users/me/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpresponse.rb:101:in `send_response'
/Users/me/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/httpserver.rb:86:in `run'
/Users/me/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'
Original Question:
I'm creating a form for users to sign up to win an ipad. It's got two fields, email and name.
When I submit the form, I keep getting the same error message no matter what email i enter
1 error prohibited this from being saved:
There were problems with the following fields:
Email has already been taken
Strangely, when I debug params, it shows whatever new email address I enter.
utf8: "\xE2\x9C\x93"
authenticity_token: UgkHFLBfKYM2tZ11u6ItWvPS5XeTIMhFuJDwvhgqe30=
ipad: !map:ActiveSupport::HashWithIndifferentAccess
name: Amy
email: franz#gmail.com
commit: Sign up
action: create
controller: ipads
Anyone have any idea? I'm a bit of a noob...
I'm just adding this code to an Enki blog I'm making on Rails...
I have this validation on my ipad.rb model (note, I had a column for a Twitter address in the migration that I'm just ignoring in the form)
attr_accessible :name, :email, :twitter
validates :name, :presence => true,
:length => { :maximum => 50 }
validates :email, :presence => true,
:uniqueness => true
This is my ipads_controller.rb
class IpadsController < ApplicationController
def new
#ipad = Ipad.new
#title = "iPad Contest"
end
def create
#ipad = Ipad.new(params[:ipad])
if #ipad.save
redirect_to 'root_path'
else
#title = "Poo"
render 'new'
end
end
end
This is my new.html.erb
<h1>Win an iPad</h1>
<%= #title %>
<h1>Sign up for iPad</h1>
<%= form_for(#ipad) do |f| %>
<%= render 'shared/errror_messages' %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= debug params %>
Using redirect_to root_path instead of redirect_to 'root_path' fixed it. Noob error.

Resources