How to get application context in Rails - ruby-on-rails

I have a URL like http://myapp.myorg.com/MyApp/one/two and I want to extract the first part myapp.myorg.com/MyApp/ in the Rails code. Please help me in getting this URL correct.
I'm currently using $servlet_context for this purpose, but it does not give me the result.
My code snippet:
<%= link_to "My Link", "{#hostname}/#{$servlet_context}/three/four" %>.
This gives me a URL like:
myapp/org.jruby.rack.servlet.ServletRackContext#622209db/three/four
I'm expecting something like:
myapp/MyApp/three/four

You can probably get this by extracting the first part of your path by defining this in your controller:
def context_path(url)
URI.join('/' + request.fullpath.split('/')[1], url)
end
helper_method :context_path
Then that's easy to incorporate into your URL:
<%= link_to "My Link", context_path('three/four') %>

Related

How to create a href tag with link_to and action 'create'

I want to create a href tag like href=contacts/create. In my contacts_controller, I have a create GET action. I know this is against rails convention. I still need to create the above link using options = {controller=> 'contacts', action=>'create'}. It works for any other arbitrary action name
You can the hardcoded path option:
<%= link_to "Create", "contacts/create" %>
or the Rails generated path option:
<%= link_to "Create", { controller: "contacts", action: "create" } %>
This is not just against Rails' convention, but against sounds HTTP usage. This often causes serious problems that you can't predict in advance. Web crawling is just one of them, where something like the Google bot accidentally creates a new contact in your database, simply by crawling the page. Or script kiddies who find you have a create link, and send 100,000 clicks to it in quick succession.
Numerous other issues happen like this, including, at one well-known time, Google Chrome pre-fetching GET urls from the page to "speed up the user experience"; this was felt far and wide by sites that had used this technique. It's not an idle warning or a style issue: this can have a disastrous impact on your site.
First off this is really bad idea since GET requests should be idempotent. You're not just flouting convention - you're setting yourself and your users up for a really bad time since for example pressing the back and forward buttons will cause resources to be created - over and over. And there is guaranteed a better way to solve whatever you are trying to do such as:
# a "discrete form"
<%= button_to "Create contact", contacts_path, method: :post %>
# or use the rails ujs
<%= link_to "Create contact", contacts_path, method: :post %>
If you ABSOLUTELY have do this:
Rails.application.routes.draw do
get "contacts/create"
end
You can now do:
<%= link_to "Create", { controller: 'contacts', action: 'create' } %>
Congratulations, you broke the internets.
Like you mentioned, this is against rails convention, but if absolutely necessary, you can do this from your controller:
options = {controller=> 'contacts', action=>'create'}
view_context.link_to url_for(options)
If you need the href to only be the path, you can do:
options = {controller=> 'contacts', action=>'create'}
view_context.link_to url_for(options.merge(only_path: true))

Why ruby on rails link_to redirect to itself?

Lets say I have a controler test.
In test I define 3 actions:
def zah
end
def zeh
end
def zih
end
I have the views:
zah.html.erb
zeh.html.erb
zih.html.erb
and under routes.rb I have:
get 'test/zah'
get 'test/zeh'
get 'test/zih'
If I write under zah.html.erb, using code automaticaly created from rubymine IDE, this:
<%= link_to test_zeh_path%>
I will get my page source code with this:
http://localhost:3000/test/zeh
which makes the redirection from zah be itself.
running rake routes returns this:
Prefix Verb URI Pattern Controller#Action
test_zah GET /test/zah(.:format) test#zah
test_zeh GET /test/zeh(.:format) test#zeh
test_zih GET /test/zih(.:format) test#zih
Can anyone explain to me why is the link going to itself (from zah to zah) instead of another page(from zah to zeh)?
Edit:
I have found out that adding a name to a link makes the generated code works right:
<%= link_to 'zeh', test_zeh_path%>
I have seen the first usage (link_to test_zeh_path) here at 22:45.
Ruby on rails api does says that if nil name is passed then "the value of the link itself will become the name.".
As for a mistake of myself I was wondering why Dave Jones was able to create a link without a name, but he wasnt and that can be seen on his source code.
Because you have written the url in the display part.
You can simply do
<%= link_to 'Goto Zeh', test_zeh_path %>
and you will be good to go.

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)

How can I create link to the json-view of an object in Rails?

What do I need to change in the code below to make it link to a view rendered as json?
<%= link_to 'JSON Link', #mymodel %>
So I'd like to generate the following url
http://localhost:3000/mymodels/1.json
instead of
http://localhost:3000/mymodels/1
(These urls both work as expected.)
To do this, you must specify the format:
<%= link_to 'JSON Link', your_model_path(#mymodel, :format => 'json') %>
The URL helper methods can be retrieved by running:
rake routes
The first column is the name of the helper method, on which you should append either _path or _url, the latter will generate an absolute URL.
More information is in the Guide To Rails Routing

What Ruby construct does the link_to method in Rails use?

Say I have this route:
match '/somepage' => "home#somepage"
I can then do this on a different page to link to "somepage":
<%= link_to "Some Page", somepage_path %>
I'm new to both Ruby and Rails, and I'm struggling to understand how exactly the "somepage_path" part works. It's not a string, it's not a symbol, is it a method call? If so, where does that method exist? Seems like I'm missing something obvious...
On initialization all paths are generated according to the routes.rb definitions.
If you want to customize the routes names you can use
match '/somepage' => "home#somepage", :as => "foobar"
Later used as
<%= link_to "Some Page", foobar_path %>
Hope that clears some stuff up about custom routing :)
Link magic is all handled by ActionDispatch::URL::UrlFor, see ActionDispatch::URL::UrlFor

Resources