MKK
MKK

Reputation: 2753

Why validation error won't appear?

In my situation, somehow it doesn't show validation error message even if there was validation error.

For example, I leave these 2 column as empty, and make sure that captcha word is typed in. Then if I try to create new record. It won't show validation error:( It comes back to the form but no message.

I've been using validation error message all the time in this project , and I never faced this problem.

Anyone can find the problem here?

Validation in Topic model

validates :title,   
    :presence => {:message => "can't be empty" },    
    :uniqueness => {:message => "choose unique title" },    
    :length => { :maximum => 20, :message => "must be less than 20 characters" }

validates :body,   
    :presence => {:message => "can't be empty" },    
    :length => { :maximum => 500, :message => "must be less than 20 characters" }

Form

<%= form_for([@community, @topic]) do |f| %>
.....

    <%= button_tag( :class => "btn btn-primary") do %>
    Create
    <% end %>

<% end %>

topic_controller

before_filter :simple_captcha_check, :only => [:update, :create]

def simple_captcha_check
    if !simple_captcha_valid?
        flash[:error] = 'wrong captcha'
        if request.put?
            @topic.attributes = params[:topic]  
            render :action => :edit
        elsif request.post?     
            @topic = Topic.new params[:topic]
            render :action => :new
        end
    end
end


def create
    @topic = @community.topics.build (params[:topic]) 
    @topic.user_id = current_user.id

    respond_to do |format|
        if @topic.save
            format.html { redirect_to community_topic_path(@community, @topic), notice: 'Created' }
            format.json { render json: [@community, @topic], status: :created, location: @topic }
        else
            format.html { render action: "new" }
            format.json { render json: @topic.errors, status: :unprocessable_entity }
        end
    end
end

routes.rb

resources :communities do
     resources :topics
end

UPDATE:

views/layouts/application.html.erb

.....
<% flash.each do |name, msg| %>
  <div class="alert alert-<%= name == :notice ? "success" : "error" %>">
    <a class="close" data-dismiss="alert">&#215;</a>
    <%= content_tag :div, msg, :id => "flash_#{name}" if msg.is_a?(String) %>
  </div>
<% end %>
.....

Upvotes: 1

Views: 556

Answers (1)

Aditya Sanghi
Aditya Sanghi

Reputation: 13433

Flash doesnt appear until the next request. So if you were doing a "Redirect" it would appear.

You are however, doing a render not a redirect. When you render, you return the body of the view itself.

But no worries, If you want to render a view (which is just fine), use the flash like this -

flash.now[:error] = 'wrong captcha'

The .now ensures that the flash gets flushed in the view of the render within the same request.

EDIT:

The reason your validations dont appear (when captcha fails) is because your before_filter does rendering and stops the create action from even being called. @topic validations only fire at @topic.save in create but since that never gets called (when captcha fails), nothing related to attribute validations appears there.

Secondly, flash.now[:error] will ensure that flash message doesnt get transferred to the next request since you intend to use in the same request's response. If however you set flash[:error] and render, then your flash message WILL appear in the same request's response AND the next request too. This should answer @saurabh's good question above and solve the mystery?

FINAL EDIT: @MKK had to include an error displaying partial which was missing from the view.

Upvotes: 5

Related Questions