Passing error messages through flash

2020-02-20 06:55发布

What is the best way to push error messages on redirect to?

I've previously used couple of approaches, but both of them has issue.

(1) Passing the entire object with error on flash and using error_messages_for:

  def destroy
    if @item.destroy
      flash[:error_item] = @item
    end
    redirect_to some_other_controller_path
  end

I found that this method causes cookie overflows.

(2) Passing a single error message:

  def destroy
    if @item.destroy
      flash[:error] = @item.full_messages[0]
    end
    redirect_to some_other_controller_path
  end

This way I only send a single error message, what if there are many? Does Anyone knows a better way?

5条回答
Rolldiameter
2楼-- · 2020-02-20 07:33

This is what worked for me:

@item.errors.messages.map { |k,v| v }.join('<br>').html_safe
查看更多
老娘就宠你
3楼-- · 2020-02-20 07:39

Firstly, you can achieve what you're trying to do by setting a single sentence.

flash[:error] = @item.errors.full_messages.to_sentence

I think you could also set it as the array without overflowing the cookie.

flash[:error] = @item.errors.full_messages

But as the other guys say, flash is generally better off being used to return specific messages.

eg.

flash[:error] = "We were unable to destroy the Item"

A common pattern is as such.

def some_action
  if @record.action
    flash[:notice] = "Action performed successfully"
    redirect_to @record      
  else
    flash[:error] = "Action failed"
    render :action => "some_action"
  end
end

Namely, we have two paths.

  1. Action succeeds. We redirect.
  2. Action fails. We show a page, flash an error, and have @record.errors on hand to call error_messages_for(@record) if we so wish.
查看更多
家丑人穷心不美
4楼-- · 2020-02-20 07:40

One of the answers to Rails validation over redirect suggests using a new clone_with_errors to do a shallow clone of the model's object instance. I guess that might help stay below the 4k limit; however I can imagine that for complex models there could still be problems, e.g. see this page written in 2007 which advocates against storing model object instances in the session.

查看更多
The star\"
5楼-- · 2020-02-20 07:42

Since flash[:error] is a hash, you can pass error messages to it with an "<<" operator

查看更多
时光不老,我们不散
6楼-- · 2020-02-20 07:54

Flash is a part of the Rails session which is cleared among requests and Rails session is implemented using cookies. (atleast until Rails-2). Cookies generally are used to store very minimal amount of data as the maximum amount the default cookie can store is 4 kbs i think. So storing the entire model objects might not be a very good option. To do that you can use a different cookie store which would allow you to store large amount of data.

As for the second problem, you can store as many error messages in the flash variable. The way you did flash[:error], you can do the same and store other messages as well using other keys to store other messages.

Hope this helps.

查看更多
登录 后发表回答