I have a search function which allows a user to search for items. From the generated list, the user can add items to a list. After adding an item from the list, the page reloads and the user is returned to their current search list. However, currently, if a user has not searched for anything, and just adds an item of the top of the list (starting at 'A, for example), when the page reloads it includes a blank search query in the url. I know why, it is because of this line
redirect_to admin_job_job_products_path(#job, search_term: params[:search_term])
I want to make the last argument in the redirect path a conditional one so that, if say the :search_term == nil || == "" || " " then the redirect_to only includes the first argument.
How would I best achieve this?
Thanks in advance!
You can do:
if params[:search_term].present?
redirect_to admin_job_job_products_path(#job, search_term: params[:search_term])
else
redirect_to admin_job_job_products_path(#job)
end
Or
redirect_to admin_job_job_products_path(#job, search_term: params[:search_term].presence)
References:
.present? method documentation
.blank? method documentation
The second example of MrYoshiji probably will not work, but you can write it short and simple this why:
redirect_to admin_job_job_products_path(#job, search_term: params[:search_term].present? ? params[:search_term] : nil)
So if the result will be nil rails will not include that param in the url
Related
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.
I have an action in a controller that I call from two different views. In each case, I want the action to redirect back to the page on which the link was clicked. At the moment I am doing this...
In this view I am passing a parameter like this...
%a.showtooltip#wprofile{:href => idea_vote_up_path(#idea, :source => 'idea'), :title => 'Awesome idea - vote up !', }
and in the controller...
if params[:source] == 'idea'
redirect_to idea
else
redirect_to ideas_path
end
This works fine, but does not feel elegant, especially as it ends up being in a few actions. Is there a better way?
You can rewrite it in following way:
redirect_to params[:source] == 'idea' ? idea : ideas_path
If you want to redirect back to the page (refresh current page)
redirect_to request.referer
Store the referrer in the session like so session[:previous] ||= request.referer and use it as redirect_to session.delete(:previous)
I find that a good way is to have a hidden input with the value you'd like to be as the return url. Seems like an easily manageable solution and has worked for me. This way you can create the hidden input in 1 or 1000 views and have a single line of code in the controller to do the redirects. I can't immediately think of what the cons to this approach would be.
In form
hidden_field_tag(:redirect_to, params[:redirect_to]) # in the form that is to be submitted, value determined by a query string
hidden_field_tag(:redirect_to, "/a/direct/value") # in the form, value specified directly
In controller
redirect_to params[:redirect_to].presence || idea_path(#idea)
Didn't test the code and don't know ruby sups well so double check but the logic should stand. The ".presence" takes care of situations where you don't want a custom redirect to and have no hidden input to specify.
I'm displaying certain items in my navigation bar depending on the current page. When I go to my sign in page the correct items are displayed. If I sign in with an incorrect password the items change and are incorrect.
In my html I check if (current_page?(new_user_session_path))
After the incorrect password is submitted and the page reloads this condition isn't returning true and it's displaying the wrong items in the navbar. I looked through the requests on the server logs and I'm guessing it's because the second time around the page loads after a POST (the unsuccessful password submission). Is there a different path I need to check for the second time?
Expanding on Scott's answer, you could create a helper in app/helpers/navigation_helper.rb for instance, like so:
module NavigationHelper
def current_location?(*args)
options = args.extract_options!
options.each do |key, val|
return false unless eval("controller.#{key.to_s}_name") == val
end
true
end
end
And use it this way:
current_location?(controller: 'my_controller', action: 'new')
current_location?(controller: 'my_controller')
current_location?(action: 'new')
In your view you can then do something like:
# Change this according what your really need
if current_location?(controller: 'sessions', action: 'new')
Hope it helps ; )
If you look at the source code of current_page?, it always returns false if the request's HTTP mode is anything other than GET or HEAD:
http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-current_page-3F
def current_page?(options)
unless request
raise "You cannot use helpers that need to determine the current " "page unless your view context provides a Request object " "in a #request method"
end
return false unless request.get? || request.head?
...
So even if your incorrect form is at exactly the same path as new_user_session_path, your logic won't match.
You may want to consider comparing controller.controller_name and controller.action_name directly instead. Not exactly elegant, but it's going to be more reliable.
I have two different ways to access the url "localhost:3000/childrens/new".
I have a drop down in childrens/new page and when the user selects an option through the drop down, it shows the different partials using ajax to call the childrens#new method.
accessing the childrens new page from url "localhost:3000/parents"
accessing the childrens new page from url "localhost:3000/parents1"
After the children have been successfully created, the user should be redirected to the relevant url (either localhost:3000/parents or localhost:3000/parents1)
Store the value in session like session[:last_request] in parent
After create children redirect it to session[:last_request] || session[:return_to] and after that clear the session[:last_request]
There are more than one way of how you can achieve this.
One solution would be to store the referrer inside of the session/cookie when the childrens/new is requested: (inside children_controller)
def new
session['children_new_referrer'] = request.env["HTTP_REFERER"]
#....YOUR CODE....
end
And then using that referrer value stored in session/cookie to redirect appropriately:
def create
#.....YOUR CODE....
if #child.save
format.html {redirect_to (session['children_new_referrer'] || parents_path)}
#.....YOUR CODE....
end
where #child is the object which I assume you are building with the parameters, and parents_path is being defined through your routes. Feel free to adjust these two based on your needs.
An alternative solution would be to not use sessions, but instead save the referrer uri/path inside of the children/new form page itself. This alternative has the benefit of making the solution session/request scope independent with handling the requirement of storing the referral uri/path within the page scope.
Do something like this
def create
redirect_to :back
end
redirect_to :back should come after save.
Pass the referrer as a parameter in the link. I would much prefer this solution to using the session store.
<%= link_to "New child", new_child_path(referrer: #parent.id) %>
.. or whatever you want to call it. Then you can inspect params[:referrer]. You're not wanting to persist data across a 'session', so why use the session store.
request.url
in your controller gives the url you are asking for.
So,
def create
if #child.save
redirect_to request.url
end
end
will do the job perfectly
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")