Forum: Ruby on Rails error_messages_for does not display the error

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
0eb550439a8bacbf55b3d9b8cb52e53b?d=identicon&s=25 Steve (Guest)
on 2009-04-02 18:54
(Received via mailing list)
Hi all

I've approached Rails since a couple of months to develop a quick
application for my company. Fantastic framework. As every noob, I do
have some gaps to cover. The one which is giving me a little
frustration, generated by my lack of knowledge is as follows.

I need to make sure the region object is not deleted if there are
countries associated with it. I solved this by putting a
before_destroy methon in the model, as follows:

class Region < ActiveRecord::Base
  has_many :countries

  validates_presence_of :name
  validates_uniqueness_of :name

  def before_destroy
    unless countries.count == 0
      errors.add_to_base "Cannot delete a region with countries
associated"
      return false
    end
  end
end

This prevents the deletion if countries are associated to it. By
adding the error to the errors collection of the region object, I
expected to receive a message on the page by adding the follwing in
the application layout

---cut---
<%= error_messages_for :region %>
<%= yield :layout %>
---cut---

actually the error_messages_for is much longer as it lists all the
objects. The tag works for input forms, but in this specific scenario
no error message is displayed.

The error is however populated, I verified it with the logger.info in
the various steps.

After crushing my head trying to figure out why, I gave up the old
way, finding another solution. But I do not like it because ruby and
rails are very elegant in their syntax. Here is what I did: in the
controller I modified the destroy method like this

  def destroy
    @region = Region.find(params[:id])
    @region.destroy

    @region.errors.each_full{|msg| flash[:error] = msg } unless
@region.errors.count == 0

    respond_to do |format|
      format.html { redirect_to(regions_url) }
      format.xml  { head :ok }
    end
  end

I know, it's an horror, I can name many resons why including the fact
that only the last error is displayed, but could not figure out a
better way. I'm pretty sure that the solution is right in front of me
but cannot find it....

Any suggestion very welcome.

Thanks
Af2ce6689213fdb78913a9662b18da6b?d=identicon&s=25 Rick (Guest)
on 2009-04-02 23:33
(Received via mailing list)
This might help you out...

http://api.rubyonrails.org/classes/ActionControlle...

Although it's not immediately apparent from the rdocs, you can flash
[:error] in addition to the documented flash[:notify] - think of them
as "alerts" and "alarms".  If you carry the error/notify distinction
into the erb with:

     <% if flash[:notice] %>
       <div class="notice"><%= flash[:notice] %></div>
     <% end %>
      <% if flash[:error] %>
       <div class="error"><%= flash[:error] %></div>
     <% end %>

you can use the class to provide css color decoration (notice <=>
yellow, error <=> red)

Just be aware that the flash is a temporary buffer - the text is
volatile by default - and refreshing the window will erase the
message.
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2009-04-02 23:35
(Received via mailing list)
On Apr 2, 10:32 pm, Rick <Richard.T.Ll...@gmail.com> wrote:
> This might help you out...
>
> http://api.rubyonrails.org/classes/ActionControlle...
>
> Although it's not immediately apparent from the rdocs, you can flash
> [:error] in addition to the documented flash[:notify] - think of them
> as "alerts" and "alarms".  If you carry the error/notify distinction
> into the erb with:
>
To extend on that, flash is just a hash (which happens to be stored in
the session and which rails clears out appropriately) - you can store
anything you want in it, for any key you want.

Fred
0eb550439a8bacbf55b3d9b8cb52e53b?d=identicon&s=25 Steve (Guest)
on 2009-04-03 14:14
(Received via mailing list)
Hi all

I found the solution to my problems...

My mistake (of course because of ignorance) was to look in the wrong
place. The error populated in the model.errors hash are rendered by
the error_messages_for method only if the render method in the
ActionController is invoked.

Therefore the code should look like this.

The model:

class Region < ActiveRecord::Base
  has_many :countries

  validates_presence_of :name
  validates_uniqueness_of :name

  def before_destroy
    unless countries.count == 0
      errors.add_to_base "Cannot delete a region with countries
associated"
      return false
    end
  end
end

The method destroy in the controller

  def destroy
    @region = Region.find(params[:id])

    respond_to do |format|
      if @region.destroy
        format.html { redirect_to(regions_url) }
        format.xml  { head :ok }
      else
        format.html { render :action => "show" }
        format.xml  { render :xml => @region.errors, :status
=> :unprocessable_entity }
      end
    end
  end

Et voilà, here is the error displayed on screen...

Steve
This topic is locked and can not be replied to.