Rails redirect_to with params - ruby-on-rails

I want to pass parameters (a hash) to redirect_to, how to do this? For example:
hash = { :parm1 => "hi", :parm2 => "hi" }
and I want to redirect to page /hello
URL like this: /hello?parm1=hi&parm2=hi

If you don't have a named route for /hello then you'll have to hardcode the params into the string that you pass to redirect_to.
But if you had something like hello_path then you could use redirect_to hello_path(:param1 => 1, :param2 => 2)

Instead of:
redirect_to some_params
You can do:
redirect_to url_for(some_params)
You're turning the params into a url with url_for before passing it to redirect_to, so what you pass redirect_to ends up being a URL as a string, which redirect_to is happy to redirect to.
Note well: I don't understand why redirect_to refuses to use params. It used to be willing to use params. At some points someone added something to Rails to forbid it. It makes me suspect that there are security reasons for doing so, and if so, these security reasons could mean that manually doing redirect_to url_for(p) has security implications too. But I haven't yet been able to find any documentation explaining what's up here.
update: I've found the security warning, but haven't digested it yet: https://github.com/rails/rails/pull/16170

The easiest way (if it's not a named route) will be:
redirect_to "/hello?#{hash.to_param}"
See: http://apidock.com/rails/Hash/to_param

Simply, pass the hash into an argument in the URL, and in your code parse it to get out all needed values.
param_arr = []
hash.each do |key , val|
param_arr << "#{key}=#{val}"
end
params_str = param_arr.join("&")
redirect_to "http://somesite.com/somepage?#{params_str}"
I know this might be very basic way to do it, but hey, it'll get you somewhere :)

Related

Replace GET params in redirect_to request.referer

I'm trying to Replace GET params in:
redirect_to request.referer
My request.referer already contains one parameter:
http://www.foo.com/bar?par=10
When i try:
redirect_to request.referer, :par => 5
it doesn't work. It redirects to referer but doesn't change :par from 10 to 5.
When i do redirect to url_path, e.g.
redirect_to root_path, :par => 5
This works ok, redirects to:
http://www.foo.com/?par=5
So my question is how to replace params in request.referer URI. Additional question is whether should I use request.referer or :back ?
Thanks
The problem is that redirect_to ultimately just takes a string, ie the url. If you were to do something like
redirect_to edit_foo_path(#foo, :bar => "qux")
then you're using a path helper to generate that string. ie, edit_foo_path(:bar => "qux") is the helper and it will be converted to "/foo/123/edit?bar=qux" which is just a "dumb" string. If you were working with the helper you can switch the params around but with the string it's already finished, if you know what i mean.
request.referer is a string as well, so what you'll need to do is to break it down into its constituent parts, modify those parts as required, and then reassemble it into a string again. The parts in question are protocol, host, path & params. You don't need to change the protocol, host or path in this case so you can keep them the same. params will be most easily manipulated when converted to a hash. Rails has various url-processing functions which you can use here, so there's probably a few different ways of doing this. I would do this like follows, which probably isn't the most efficient.
url = URL(request.referer)
#you could get this via a regex but i'm doing it "formally" with the Url object
host_and_path = "#{url.scheme}://#{url.host}#{url.path}"
params = CGI.parse(url.query)
#now you've got params as a hash you can do what you want to it.
params["par"] = 5
new_url = "#{host_and_path}?#{params.to_param}"
redirect_to new_url
like i say there's probably more efficient (in terms of lines of code, there's no issues with it speed-wise) ways to do this, but it's useful to see the step-by-step approach anyway i guess.

Setting Up Rails to Receive HTTP POST Request

Is setting up Rails to receive a HTTP POST request that sends information encoded in JSON form as easy as adding the following code to the sessions_controller? Or are there other steps involved?
def create
if user = User.authenticate(params["email"], params["password"])
session[:user_id] = user.id
render:json => "{\"r\": \"t\"}" + req
else
render :json => "{\"r\": \"f\"}"
end
end
Should be that easy, though you will need to add a route to your routes.rb file as well specifying POST as the HTTP verb and pointing it to sessions#create. You also might want to use strong parameters just to validate what parameters are required and which you'll accept. As a heads up, I'm not entirely sure what "{\"r\": \"t\"}" + req is supposed to represent. It looks like req would be undefined in this case, but perhaps you're just omitting some code. Lastly, render :json => ... is sort of the old way of including a hash. I believe as of Ruby 2 the standard is something more like render json: .... Hopefully that helps.

Rails: redirect_to '#{user.role}_url' how do I accomplish this?

Is there a way in rails/ruby to simplify my routing code to be elegant like:
redirect_to user.role + _url
This way if the user is an admin they will be routed to the admin page so on so forth for other user types...
Sure!
redirect_to send("#{user.role}_url")
in ruby, the send will execute the method on the receiver, and that's exactly what you want. Usually, that would look like:
#receiver_object.send(:admin_url)
But the url-helpers work in the global namespace, so you can send to global and have it work.
Easy way to test: Add this to a controller and watch it redirect you home:
redirect_to send("root_path")
Probably the best way would be to use the url_for helper. For example.
redirect_to url_for( :controller => users, :action => user.role )
This would generate a path /users/admin or /users/guest etc.
If you want to do it a hackish way you could use
redirect_to eval("#{user.role}_url")
Be careful with that though. The reason your string isn't working is it isn't evaluated, so redirect_to "admin_url" doesn't do anything, it's just a meaningless string and redirect is expecting the string to be a URL.
If you evaluate the string it would work, because redirect_to eval("#{user.role}_url") is going to first convert "admin_url" into calling the admin_url method, which returns some path like users/admin, and THAT string is useable by the redirect method.
You can use render "#{user.role}". Just be sure to have corresponding views with the names admin.html.erb' and so on.
I really like Andrew's answer, but you could also do something like
redirect_to send(user.role.to_s + '_url')
There are several things that you could do, but nothing built in and nothing that would be significantly simpler than send("#{user.role}_url"). Be sure to use send() - otherwise it will redirect to the URL "/admin_url" instead of calling the admin_url helper.
One such other solution would be to create an action called 'home' that would redirect to the current_user's role's page. That would add an extra redirect (slightly increase the page load time), but it would make your redirects simpler
redirect_to home_url

Redirect_to with string path

I'm trying to redirect to a location based on a param on a submitted form.
If params[:route] = group , I want to redirect to groups_path.
I tried the following method to redirect but obviously enough the groups_path is a variable and not a string. How can I redirect based off the param?
redirect_to "#{params[:route]}s_path"
Edit:
realised I can redirect to the actual path but this doesn't seem like a very rails way of doing it.
redirect_to "/#{params[:route]}s"
redirect_to send("#{params[:route].pluralize}_path")
But I'd rather write a wrapper-helper returning appropriate url helper based on the params[:route] value. params[:route] could potentially have any value and you may want to rescue in these cases.
send can calls private method, therefore better is public_send
and instead "#{params[:route]}s" use "#{params[:route].pluralize}
redirect_to public_send("#{params[:route].pluralize}_path")

Rails 3 change path to url

I am passing a path as a parameter, so params[:path] would be name_path(:username => #user.name (I want to pass it as a path and not a url, so putting name_url in the params isn't what I want).
Since you can only use redirect_to with a url, I need to change the path to a url before I can use redirect_to. How would I do this?
I found this method here
def path_to_url(path)
"http://#{request.host_with_port_without_standard_port_handling}/#{path.sub(%r[^/],'')}"
end
But, this was written in 2008, and I want to know if there is a better way in Rails 3?
Updated copy from original path to url post btw: also works on Rails 2
# abs or /abs -> http://myx.com/abs
# http://grosser.it/2008/11/24/rails-transform-path-to-url
def path_to_url(path)
"#{request.protocol}#{request.host_with_port.sub(/:80$/,"")}/#{path.sub(/^\//,"")}"
end
I think you can use a redirect_to with a path as long as its a route defined in the routes file for the current application. Thats seems to be the case from your question.
ie, name_path(:username => #user.name)
So the following should be valid.
redirect_to params[:path]
I ended up using
def path_to_url(path)
"http://#{request.host}/#{path.sub(%r[^/],'')}"
end

Resources