Topic: trying to figure out the Rails way on some code...

Here's the situation: I'm using attachment_fu in an "upload" model.  this model has validation for file sizes, content type, etc. and "validates_as_attachment"

In my /view/ method, an ID is passed in, and the user has a file field to upload a file.  this form submits to /add_file/, which looks like this:

def add_file
    @file = Upload.new(params[:tab])
    if @file.save
        flash[:notice] = "File Uploaded!"
    else
        @file.errors.each do |i|
            if i.include?("content_type")
                flash[:error] = "Error uploading file: This file type is not accepted."
            elsif i.include?("size")
                flash[:error] = "Error uploading file: file size is too large.  Please keep it under 2 megabytes."
            end
        end
    end
       
    redirect_to :action=>:view, :id => params[:tab][:tab_id]       
end

this is working fine, however, there must be a better, more efficient way.  What I tried to do in the view.rhtml for /view/ is to put: error_messages_for :tab, and ditch the whole @file.errors loop in favor of a redirect, but that didn't work because the redirect cleared out the errors.

so my next attempt was to replace the redirect with a render_action, however this got bloated quick as I needed to set params[:id] = params[:tab][:tab_id] to emulate /view/some_id, then call the method itself so it would run some of the queries I have that reply on an ID in the URL, then do the render_action.  All said and done, my error_messages_for still didn't output a thing.

so that brought me to make this post to try and progress with my understanding of rails.  inch by inch...

Re: trying to figure out the Rails way on some code...

bump

Re: trying to figure out the Rails way on some code...

Keep the errors_for in the view and use render instead of redirect.  So

render :action=>:view, :id => params[:tab][:tab_id]

Last edited by saracen (2007-07-19 18:53:17)

Re: trying to figure out the Rails way on some code...

Correct, but in my 'view' action I have some set instance variables that rely on an ID being passed in.  Thus, when I try your code, I get "You have a nil object when you didn't expect it!" because these variables are not being initialized.

render :action only processes the .rhtml for that action, not the action itself, right?

Re: trying to figure out the Rails way on some code...

That's correct.  Calling render only renders the template (rhtml).  If you need instance variables you'll have to set them up in the calling method, so add_file in your case.  If you want to refactor the code that sets them up so that you aren't repeating yourself in add_file and in view, then you could add that to a helper method for your controller.

Last edited by saracen (2007-07-19 19:54:26)

Re: trying to figure out the Rails way on some code...

On another note, you know that the flash is available to the next request so if your error messages are there then you can still display them.  That's one of the reasons that the flash exists in the first place.