My Rails application uses a custom FormBuilder and a Model not associated to a database table to deal with user comments. If I validate the form and it fails, I render the new
view with errors, but the original input to the fields does not show. If I view the parameters, they are showing there.
Parameters:
Parameters: {
"utf8"=>"✓",
"authenticity_token"=>"ofJbUSioJ9w+c6EkPy993jtBskYMK/97gp667ACWZDI=",
"message"=>{
"name"=>"a",
"email"=>"a",
"comment"=>"a"
},
"commit"=>"Send"
}
Rendered view:
<form accept-charset="UTF-8" action="/contact_us" class="new_message" id="new_message" method="post">
<div style="display:none">
<input name="utf8" type="hidden" value="✓" />
<input name="authenticity_token" type="hidden" value="ofJbUSioJ9w+c6EkPy993jtBskYMK/97gp667ACWZDI=" />
</div>
<label class="" for="message_name">
Name
<input class="" id="message_name" label="Name" name="message[name]" type="text" />
</label>
<label class="error" for="message_email">
Email
<input class="error" id="message_email" label="Email" name="message[email]" type="text" />
</label>
<small class="error">Is invalid</small>
<label class="" for="message_comment">
Comment
<textarea class="" id="message_comment" label="Comment" name="message[comment]" rows="10">
</textarea>
</label>
<input class="button round right" name="commit" type="submit" value="Send" />
</form>
Controller:
def create
@message = Message.new(message_params)
if @message.valid?
flash[:success] = "Thank you for your message, we will be in touch shortly."
redirect_to root_path
else
flash.now[:alert] = "Oops! You have not filled out the form correctly. Please try again."
render 'new'
end
end
private
def message_params
params.require(:message).permit(:name, :email, :comment)
end
Model:
class Message
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :email, :comment
validates :name, presence: true
validates :email, presence: true, format: { with: /@/ }
validates :comment, presence: true
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
FormBuilder:
class FoundationFormBuilder < ActionView::Helpers::FormBuilder
delegate :content_tag, to: :@template
delegate :label_tag, to: :@template
def text_field(method, options = {})
options[:label] ||= "#{method.to_s}".humanize
options[:class] ||= ""
field_errors = object.errors[method].join(', ') unless object.errors[method].blank?
options[:class] << "error" if field_errors
options = objectify_options(options)
options.delete(:object)
label = lambda do
label_tag("#{@object_name}[#{method}]", "#{options[:label]}", class: "#{'error' if field_errors}") do
label = "#{options[:label]}"
options.delete(:label)
label << @template.send('text_field_tag', "#{@object_name}[#{method}]", nil, options)
label.html_safe
end
end
error_messages = lambda do
content_tag(:small, field_errors.humanize, class: "error") if field_errors
end
"#{label.call} #{error_messages.call}".html_safe
end
def text_area(method, options = {})
options[:label] ||= "#{method.to_s}".humanize
options[:class] ||= ""
field_errors = object.errors[method].join(', ') unless object.errors[method].blank?
options[:class] << "error" if field_errors
options = objectify_options(options)
options.delete(:object)
label = lambda do
label_tag("#{@object_name}[#{method}]", "#{options[:label]}", class: "#{'error' if field_errors}") do
label = "#{options[:label]}"
options.delete(:label)
label << @template.send('text_area_tag', "#{@object_name}[#{method}]", nil, options)
label.html_safe
end
end
error_messages = lambda do
content_tag(:small, field_errors.humanize, class: "error") if field_errors
end
"#{label.call} #{error_messages.call}".html_safe
end
end
Why are the fields not picking up the values in the parameters hash? Is this a result of my custom FormBuilder or is there some other issue?