How can I call another controller's action (or better yet, h


#1

I’ve got an action that runs, and when it’s done I want the user to
POST to another URL. However I don’t want to display a form that they
need to submit.

The two ideas I’ve had are to either call OtherController#create
directly, or to send some response to the browser that initiates a
POST back to the correct URL.

Anyone know how to do this, or have any other ideas?

Pat


#2

Hi Pat,

Pat M. wrote:

I’ve got an action that runs, and when it’s done
I want the user to POST to another URL.

I haven’t tested it with the POST, but maybe just…

redirect_to :controller => controller_name, :action => action_name,
:method
=> “post”

If redirect_to won’t take the POST, you could maybe query
controller.controller_name and/or controller.action_name to see where
the
request came from and then treat it accordingly.

hth,
Bill


#3

On Jul 6, 8:15 pm, “Pat M.” removed_email_address@domain.invalid wrote:

Pat
check out

http://drawohara.tumblr.com/post/2070878

-a


#4

AFAIK, HTTP doesn’t allow redirects using the POST method… which
makes sense. A redirect is either a “302 Found” or a “301 Moved
Permanently”, usually the former. Either of these are saying “you
asked for a resource, but it’s not here… here (the Location
header) is where to get it.” Nothing about form submission. Redirects
are always GETs.

If you want the form data to be processed as a POST in a different
controller and originating from the client, I think javascript is
about your only option. You can use the rails prototype library to
send a post from within javascript and without showing a form to the
user. I’ve done this many times.

However, I’m not sure that that’s what you really want. What is it
that the first action is doing? Was it handling a form submission? If
the problem is that you have some logic in one action that you need in
two places, then you could pull that out into a helper method in
application_helper. You can also do common side-processing in
filters.

I haven’t done your idea of calling an action from within another
action, but that might work. Just remember that is a regular method
call, so control will return to the caller after the called action is
done. And you can only call render in there once, so you’d need
conditionals around the render calls if there’s more than one.

Well, I hope something in there helps…

Ben


#5

why not just call the create method and return when the user doesn’t
need to see the preview?

def final_step

create() and return

end

the whole js onload thing seems a bit gnarly!

worse case… to DRY things up… I would say just put the logic in a
shared module and call it from your controller methods?

good luck!
Tim


#6

The user goes through a workflow, updating a db record in a series of
steps. When the whole thing is done, we create another record (of a
separate class).

The problem is that sometimes they have a final Preview step and
sometimes they don’t. When the user has a preview step, I show a
filled in form. They submit it, our record is created, all is good.
When they don’t have a preview step though, we never see this page.
So I have to handle it before that, when they complete the final step
of the workflow.

So basically they same logic goes in the VideosController#create
method and the final step of the workflow. That sucks.

I think a reasonable approach is, if the user doesn’t have a preview
step, redirect them to a blank page that has the form in it. Use
page.onload to automatically submit the form. This way I keep all the
final creation logic in one place.

Thoughts?

Pat


#7

I need to run a couple more statements than just the create. It’s
creating associated objects, but I don’t think it should be done as
part of a create hook. There’s only like three lines that need to be
duplicated. So I guess I’ll move it into a module.

I think I might be missing something though. So let me give a bit more
detail.

class Video < AR
has_many :assets
end

class Asset < AR; end

The create is going to be a simple
@video = Video.create params[:video]

From here I need to create a couple assets. I could just do this in
a create hook, except for the fact that I need to pass them a frame
number. This never gets stored anywhere but gets sent back to a
transcoding server.

So I feel weird about putting a frame_number accessor on either Video
or Asset. They’d only ever use it once, and it just seems like it
shouldn’t go there.

Doing this all in a create hook would also make testing tougher
because I’d have to stub lots of stuff.

I think what I should do is write a new builder/method or class that
handles all of this. I can call that method, passing it all the info
I need, and it will create the video, the assets, and tell the other
server about it. That way I can encapsulate the entire building
process by one method, so I don’t have any duplication, and my AR
classes stay lightweight and don’t have to worry about constructing
all these other things.

Sorry if that’s a bit rambly, it’s basically me talking things
through. Thanks for listening :slight_smile:

Pat


#8

I’d do this in the Video model, even if it touches things (like
frame_number) that don’t get persisted to a database, it sounds like a
create_with_assets method that does what you say will just implement
your “business rules” where a video needs to be created together with
those assests under some circustamces (and just having a “fat” model
is not bad if it helps to better define the domain model and its
associated rules)

just my 2c.

Luca M.

2007/7/10, Pat M. removed_email_address@domain.invalid: