Rails current url helper - ruby-on-rails

Apologies for such a simple question, but I couldn't been able to solve it myself after hours since my RoR knowledge is basically nonexistent. In the Rails application I'm working with, has been used a navigation helper to highlight active menu:
def nav_link(link_text, link_path, ico_path)
class_name = current_page?(link_path) ? 'active' : nil
content_tag :li do
link_to(link_path, class: class_name) do
image_tag("icons/#{ico_path}.svg") + content_tag(:span, link_text)
end
end
end
The circumstances have changed and current_page? is no longer a viable option, since routing now handled on the front-end. Is there a way to achieve the same functionality by retrieving, for instance, current url and check it against link_path?. I've tried a lot of things with different helpers like request.original_url, but to no avail.

request.original_url should work according to the documentation.
Returns the original request URL as a string
http://apidock.com/rails/ActionDispatch/Request/original_url
You could also try string concatenation with different variables.
request.host + request.full_path
If that doesn't work either, you could try
url_for(:only_path => false);

Use
request.url
http://api.rubyonrails.org/classes/ActionDispatch/Http/URL.html#method-i-url
or
request.path
http://www.rubydoc.info/gems/rack/Rack/Request#path-instance_method

You'll want to look at the active_link_to gem:
def nav_link(link_text, link_path, ico_path)
content_tag :li do
active_link_to link_path do
image_tag("icons/#{ico_path}.svg") + content_tag(:span, link_text)
end
end
end
Unlike the current_page? helper, active_link_to uses controller actions and model objects to determine whether you're on a specific page.
current_page? only tests against the current path, leaving you exposed if you're dealing with obscure or ajaxified routes.
--
I was going to write about how current_page? works etc, but since you mentioned that it's nonviable, I won't. I would have to question why it's nonviable though...
routing now handled on the front-end.
Surely even if you're using something like Angular with Rails, you'd have to set the routes for your app?

Related

Injecting values into all link_to method calls in Ruby on Rails

I have a strange requirement that I need to inject a value at the beginning of all local links. This is a legacy app and is quite large so I'm looking to do it under the hood, maybe with a monkey patch.
Basically if I have a link_to "Go to dashboard", dashboard_path or link_to "Create a new Job", new_job_path that they would both generate links that look like "/some_value/dashboard" and "/some_value/jobs/new"
Tried a few things and they all have failed. Any ideas?
You can try something like this in your helper instead of monkey patching link_to.
def custom_link_to(link, url, opts={})
url = "append_here/"+url
link_to(link, url, opts)
end
Now you can call this action instead of calling link_to wherever applicable and also use link_to in case if you don't want to override.
custom_link_to("Go to Dashboard",dashboard_path,{})
UPDATE
In case of overriding everything, something similar to this might be helpful - Monkey patching Rails

Setting dynamic link path with url parameters in rails

I'm building an app where I set links dynamically through a url parameter. I can't figure out how to make the link_to work with both a dynamic link and further url parameters.
TemplateController
def next
#template = Template.find(params[:t])
end
Next View
<%= link_to "#{#template.firstpage_link}(:t => #template.id, :prt => 1)" do %><%end%>
This is what it gives me:
http://localhost:3000/role/step2_path(:t%20=%3E%20#template.id,%20:prt%20=%3E%201)
I've tried a bunch of ways and I get either errors or this link
What you seem to be shooting for is something like
<%= link_to public_send(#template.firstpage_link, :t => #template.id, :prt => 1) do %>
public_send lets you call a public method by passing in its name as a symbol or string.
However, there may be more elegant ways to achieve this with the Rails router, as #Typpex is suggesting. If nothing else, you could clean up the view a bit with something like this in a helper:
def template_path(template)
public_send(template.firstpage_link, :t => template.id, :prt => 1)
end
And then calling that from your view.
I think you are not using link_to correctly, if you look at the link_to API
You will see that the first parameter is what you would like to be displayed and the second one is the rails path. You should pass your parameter when defining the rails path (or plain url) such as
link_to "display text", "#{#template.firstpage_link}?t=#{#template.id}&prt=1"
it would be better if you could use a rails route like
template_path(#template, prt: 1)

Helper for edit/show/destroy Link with an image

i am trying to make nice helpers so that i can use these style:
edit(category)
destroy(post.comment.first)
show(#user)
and we get the selected link with a nice image.
can anyone tell me if i am doing it right or is there a better magical rails way to get the url?
def show(object)
link_to image_tag("admin/show.png"), eval("admin_{object.class.to_s.downcase}_path(# {object.id})")
end
def edit(object)
link_to image_tag("admin/edit.png"), eval("edit_admin_#{object.class.to_s.downcase}_path(#{object.id})")
end
def destroy(object)
link_to image_tag("admin/destroy.png"), eval("admin_#{object.class.to_s.downcase}_path(#{object.id})"), :method=>:delete, :confirm=>"Do you really want to delete this?"
end
this is working fine but i am looking for the magic rails way :-)
replace eval with send, and replace downcase with underscore which is rails' convention
send("admin_{object.class.to_s.underscore}_path", object.id)
BTW, rails can do these for you:
# equals to your `show(object)`
link_to image_tag('admin/show.png'), [:admin, object]

How to mixin and call link_to from controller in Rails?

This seems like a noob question, but the simple answer is eluding me. I need to call link_to in an ActionController method to spit out an HTML link. ActionView::Helpers::UrlHelper.link_to calls url_for, but this calls the AV module's version instead of the controller's. I managed to coerce this into doing what I intended by putting
#FIXME there must be a better way to mixin link_to
alias_method :self_url_for, :url_for
include ActionView::Helpers::UrlHelper
alias_method :url_for, :self_url_for
in the controller. But, I'm still not sure why it works exactly. Could someone please explain the method scope and hiding that's happening here? What's a better way to mix in link_to (or generally, to include only some methods from a module) so I can call it in the controller (generating a flash string with a link is the use case.)
Please, no lectures about MVC--if anything, link_to should be in a module separate from url_for. Judging from the amount of noise on this, lots of people run into this seemingly trivial snag and end up wasting an hour doing it the "Rails way" when really what is wanted is a one minute hack to make my app work now. Is there a "Rails way" to do this with helpers perhaps? Or a better ruby way?
Compatible with Rails 3,4 and 5:
view_context.link_to
This doesn't really answer your question but there is an easier way
For Rails 5, use the helpers proxy
helpers.link_to '...', '...'
For Rails 3 and 4, since you are using the helper from a controller you can use the view_context
# in the controller code
view_context.link_to '...', '...'
# instead of using your mixin code
link_to '...', '...'
For Rails 2, since you are using the helper from a controller you can actually access the #template member variable of the controller, the #template is the view and already has the UrlHelper mixed in
# in the controller code
#template.link_to '...', '...'
# instead of using your mixin code
link_to '...', '...'
if you need to use the urlhelper from code other than the controller, your solution is probably the way to go
I still had problems using my own helper methods that use built-in helper methods in a controller with ActionController.helper.my_method.
Obviously using render_to_string for each flash would work, but I don't want to create so many small partials for each flash.
My solution was to create a little helper for controllers to execute code in a partial.
The helper method in the controller:
def h(&block)
render_to_string(:partial => 'helper', :locals => {:block => block})
end
The HAML partial (helper.html.haml):
= instance_eval &block
Same would work in ERB (helper.html.erb):
<%= instance_eval &block %>
Use it like this in your controller to call the my_custom_helper_function that's defined in a helper:
redirect_to url, :notice => h{my_custom_helper_function}
You can do it like this:
ActionController.helpers.link_to("Click Me!", awesome_path)
But really, a better place to generate that link might be in a helper module where UrlHelper and other view-related helpers are already included.
[update]
This approach is outdated and no longer works.

How do I get the current absolute URL in Ruby on Rails?

How can I get the current absolute URL in my Ruby on Rails view?
The request.request_uri only returns the relative URL.
For Rails 3.2 or Rails 4+
You should use request.original_url to get the current URL. Source code on current repo found here.
This method is documented at original_url method, but if you're curious, the implementation is:
def original_url
base_url + original_fullpath
end
For Rails 3:
You can write "#{request.protocol}#{request.host_with_port}#{request.fullpath}", since request.url is now deprecated.
For Rails 2:
You can write request.url instead of request.request_uri. This combines the protocol (usually http://) with the host, and request_uri to give you the full address.
I think that the Ruby on Rails 3.0 method is now request.fullpath.
You could use url_for(only_path: false)
DEPRECATION WARNING: Using #request_uri is deprecated. Use fullpath instead.
If you're using Rails 3.2 or Rails 4, you should use request.original_url to get the current URL.
Documentation for the method is at http://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-original_url, but if you're curious, the implementation is:
def original_url
base_url + original_fullpath
end
EDIT: This is still the case for Rails 7 (Docs).
You can add this current_url method in the ApplicationController to return the current URL and allow merging in other parameters
# https://x.com/y/1?page=1
# + current_url( :page => 3 )
# = https://x.com/y/1?page=3
def current_url(overwrite={})
url_for :only_path => false, :params => params.merge(overwrite)
end
Example Usage:
current_url --> http://...
current_url(:page=>4) --> http://...&page=4
For Ruby on Rails 3:
request.url
request.host_with_port
I fired up a debugger session and queried the request object:
request.public_methods
In Ruby on Rails 3.1.0.rc4:
request.fullpath
I needed the application URL but with the subdirectory. I used:
root_url(:only_path => false)
url_for(params)
And you can easily add some new parameter:
url_for(params.merge(:tag => "lol"))
I think request.domain would work, but what if you're in a sub directory like blah.blah.com? Something like this could work:
<%= request.env["HTTP_HOST"] + page = "/" + request.path_parameters['controller'] + "/" + request.path_parameters['action'] %>
Change the parameters based on your path structure.
Hope that helps!
It looks like request_uri is deprecated in Ruby on Rails 3.
Using #request_uri is deprecated. Use fullpath instead.
Using Ruby 1.9.3-p194 and Ruby on Rails 3.2.6:
If request.fullpath doesn't work for you, try request.env["HTTP_REFERER"]
Here's my story below.
I got similar problem with detecting current URL (which is shown in address bar for user in her browser) for cumulative pages which combines information from different controllers, for example, http://localhost:3002/users/1/history/issues.
The user can switch to different lists of types of issues. All those lists are loaded via Ajax from different controllers/partials (without reloading).
The problem was to set the correct path for the back button in each item of the list so the back button could work correctly both in its own page and in the cumulative page history.
In case I use request.fullpath, it returns the path of last JavaScript request which is definitely not the URL I'm looking for.
So I used request.env["HTTP_REFERER"] which stores the URL of the last reloaded request.
Here's an excerpt from the partial to make a decision
- if request.env["HTTP_REFERER"].to_s.scan("history").length > 0
- back_url = user_history_issue_path(#user, list: "needed_type")
- else
- back_url = user_needed_type_issue_path(#user)
- remote ||= false
=link_to t("static.back"), back_url, :remote => remote
This works for Ruby on Rails 3.0 and should be supported by most versions of Ruby on Rails:
request.env['REQUEST_URI']
None of the suggestions here in the thread helped me sadly, except the one where someone said he used the debugger to find what he looked for.
I've created some custom error pages instead of the standard 404 and 500, but request.url ended in /404 instead of the expected /non-existing-mumbo-jumbo.
What I needed to use was
request.original_url
If by relative, you mean just without the domain, then look into request.domain.
You can use the ruby method:
:root_url
which will get the full path with base url:
localhost:3000/bla
(url_for(:only_path => false) == "/" )? root_url : url_for(:only_path => false)
In Rails 3 you can use
request.original_url
http://apidock.com/rails/v3.2.8/ActionDispatch/Request/original_url
you can use any one for rails 3.2:
request.original_url
or
request.env["HTTP_REFERER"]
or
request.env['REQUEST_URI']
I think it will work every where
"#{request.protocol}#{request.host}:#{request.port}#{request.fullpath}"
Rails 4.0
you can use request.original_url, output will be as given below example
get "/articles?page=2"
request.original_url # => "http://www.example.com/articles?page=2"
You can either use
request.original_url
or
"#{request.protocol}#{request.host_with_port}"
to get the current URL.
For Rails 3.2 or Rails 4
Simply get in this way "request.original_url"
Reference: Original URL Method
For Rails 3
As request.url is deprecated.We can get absolute path by concatenating
"#{request.protocol}#{request.host_with_port}#{request.fullpath}"
For Rails 2
request.url
if you want to be specific, meaning, you know the path you need:
link_to current_path(#resource, :only_path => false), current_path(#resource)
For rails 3 :
request.fullpath
request.env["REQUEST_URI"]
works in rails 2.3.4 tested and do not know about other versions.
To get the request URL without any query parameters.
def current_url_without_parameters
request.base_url + request.path
end
You can set a variable to URI.parse(current_url), I don't see this proposal here yet and it works for me.
You can use:
request.full_path
or
request.url
Hopefully it will resolve your problem.
Cheers
To get the absolute URL which means that the from the root it can be displayed like this
<%= link_to 'Edit', edit_user_url(user) %>
The users_url helper generates a URL that includes the protocol and host
name. The users_path helper generates only the path portion.
users_url: http://localhost/users
users_path: /users

Resources