0

In a Rails 3.2 app, I have a validation for an attachment type.

Attachment model:

class Attachment < ActiveRecord::Base
  validates_presence_of :name
  validates_attachment_presence :attach, :message => "No file selected"
  validate :check_type


  def check_type
    if self.costproject_id != nil
      if self.attach_content_type != 'application/pdf'
        self.errors.add(:pdf, " ONLY")
        return false
      end
    end
  end

But, the return false sends me to this URL:

http://localhost:3000/attachments

I want it to go back to the previous input screen:

http://localhost:3000/attachments/new?costproject_id=2

How do I accomplish that?

Thanks!!

UPDATE1

Perhaps the redirect has to take place in the controller?

        format.html { render action: "new" }

Attachment controller:

  # POST /attachments
  # POST /attachments.json
  def create
    @attachment = Attachment.new(params[:attachment])

    respond_to do |format|
      if @attachment.save
        format.html { redirect_to session.delete(:return_to), notice: 'Attachment was successfully created.' }
        format.json { render json: @attachment, status: :created, location: @attachment }
      else
        format.html { render action: "new" }
        format.json { render json: @attachment.errors, status: :unprocessable_entity }
      end
    end
  end

I changed this line:

format.html { render action: "new" }

To:

 format.html { redirect_to request.referer }

And now it goes back to where I want. But, I've lost the errors - they don't display.

Reddirt
  • 5,913
  • 9
  • 48
  • 126

2 Answers2

0

Try this.

Replace

 return false

With

redirect_to request.referrer || root_url

Note: root_url here is a catchall. Also this is Rails 4, I do not know if it also applies to Rails 3. Worth a try, though.

Debug ideas

First confirm a simple redirect_to root_url (or whatever name you use for your root) works in your controller

redirect_to root_url

Then, once redirect_to confirmed working, focus on getting the REST interface "request." information. There's a Rails 3 discussion here which may help you.

How to get request referer path?

Community
  • 1
  • 1
Elvn
  • 3,021
  • 1
  • 14
  • 27
0

To help you understand what's going on here. When you go to /attachments/new you are rendering a form. When you press submit, you are sending a POST request to /attachments, which invokes the create action.

You're create action appears to be solid and idomatic. However when you render action: "new" in the case of an error, it's not a full redirect, it's rendering the form in the context of the current action.

Normally this is fine, because idomatic rails would have you building a single, very similar, model object in both new and create, and the form for helper would render that object. However your new action is creating all kinds of objects based on a large assortment of query parameters, which I'm guessing is why you are seeing behavior you don't like.

I expect your final solution will involve bringing all those parameters into Attachment in some way, if they don't need to be saved to the database, you can make attr_accessors on Attachment

  # Model
  class Attachment < ActiveRecord::Base
    attr_accessor :worequest_id, :workorder_id # etc
  end

  # View
  <%= form_for @attachment do |f| %>
    <%= f.hidden :worequest_id %>
  <% end %>

Approaching it this way, your post request params will look like

  {
    attachment:
    {
      worequest_id: 1,
      # etc
    }
  }

And you would also need to rework your query params to nest the inidividual ids inside of an attachment

/attachments/new?[attachment][worequest_id]=1

This way you could build attachment from params in both actions:

Attachment.new(params[:attachment])

And now your current create action should more or less work as expected, because now it's idomatic rails.

You still aren't going to get the new action with the same query params, but since you are taking those params and filling them in hidden fields on the form, they won't be lost when you try and fail to create. In any case, unless you do something to persist the values between requests, the POST to /attachments is going to wipe out the ery params.

DVG
  • 17,392
  • 7
  • 61
  • 88