Modifying rails route helper - ruby-on-rails

I'd like to modify the behavior of the rails route helper *_url for a single route/page.
Here's what I'm try to do:
User visits:
http://test1.myapp.com/account
All the *_url routing helpers resolve to http://test1.myapp.com/ as normal.
But, then if the user goes to https://myapp.heroku.com/account/billing?id=test1
I'd like all the *_url routing helpers on that page to resolve to: http://test1.myapp.com/
instead of http://myapp.heroku.com/
So, is it possible to change the domain bit for all the *_url helper calls for a specific page?
For those interested, I'm trying to use heroku's piggyback ssl method for my app for just a secured billing page.

You can actually just modify the links that point to the billing area:
<%= link_to "Billing", my_helper_url(test1, :host => "myapp.heroku.com", :protocol => "https") %>

Related

Where default protocol is configured for rails `link_to`?

Rails link_to generates a link with http:// prfeix. But site is https.
So forms must not be used like so. And actually it is not working for most browsers.
The problem appears in spree shop. Internal templates of spree generates wrong urls. So modify spree internal templates to add protocol to each link_to is not a solution.
Where default protocol is configured for rails link_to?
You need to pass :protocol => 'https' inside the url creation.
<%= link_to "text", your_url(:protocol => "https"), :method => :post %>

Edit model - token URL

I want users to be able to edit a model through a different than the default URL /merchants/:id/edit(.:format), which will be using a token. This token is created randomly and stored in the database.
The link I want to create will be similar to this merchants/token-124512/edit.
Now I want to be able to send this link to users via e-mail. The default link with the id is link_to "link", edit_merchant_path(#merchant, :only_path => false).
How would the one with token be like? Also, how can I declare this one in the routes.rb?
Solution
First of all I would suggest to use _url instead of _path in your mailer because you want to resolve full path.
Try with:
link_to "link", edit_merchant_url(id: #merchant.token)
Why _url?
using _path will get you <a href=merchants/token-124512/edit'>link</a>, but in mail you want to know host as well so you should get this:
<a href='hostname.com/merchants/token-124512/edit'>link</a>
If you are using rails 4, you can use the new concept called 'param' in your routes, which will change the default route.
You can pass any field instead of your id.
# config/routes.rb
resources :merchants, param: :token_field
# app/controllers/merchants_controller.rb
#merchant = Merchant.find_by(token_field: params[:token_field])
Example
resources :merchants, param: :your_fleld
merchants GET /merchants(.:format) merchants#index
POST /merchants(.:format) merchants#create
new_merchants GET /merchants/new(.:format) merchants#new
edit_merchants GET /merchants/:your_field/edit(.:format) merchants#edit
Merchant.find_by(your_field: params[:your_field])
You can find the documentation here

Ruby On Rails Subdomain Convention

I have a domain, domain.com, and I want one Rails application, for example, to handle all subdomain requests, i.e., blog.domain.com, subdomain.domain.com, etc.
The Ruby on Rails framework is all about convention. So, is there a convention for creating subdomains in Rails? If so, what is it? If not, what might be some good methods for trying to get what I described above accomplished?
You could follow this tutorial on using subdomains in Rails:
http://railsapps.github.io/tutorial-rails-subdomains.html
Basically, you implement routing for subdomains like this:
match '/' => 'profiles#show', :constraints => { :subdomain => /.+/ }
Url helper methods also accepts a subdomain option so you can write url helpers like:
link_to root_url(:subdomain => user.name), root_url(:subdomain => user.name)
You'll find more details as to how to use subdomains in the link provided above.

Handling mix of HTTP and HTTPS links on a page

My setup: Rails 3.0.9, Ruby 1.9.2
My app requires that only a certain part of my site be SSL protected and the rest not. In case anyone thinks this isn't normal behavior, check out Amazon. When merely browsing for products, it's in HTTP mode, during checkout, it switches to HTTPS. Even in the middle of a secure checkout transaction, there are several other links on the same page that are HTTP only.
I looked at ssl_requirement gem and decided not to use it because it isn't a complete solution for my needs. I ended up setting up specific SSL routes like
resources :projects do
resources :tasks, :constraints => { :protocol => "https" }
end
In my view code, for HTTP specific links
<%= link_to 'Projects', project_url(#project, :protocol => "http") %>
and to handle HTTPS specific link
<%= link_to 'Task', new_project_task_url(#project, :protocol => "https") %>
I understand this isn't the cleanest way but it's what I have decided to do. The problem with this setup is how to properly set both HTTP and HTTPS links on every page. There is a proposed solution here but it requires wholesale changes _path to _url and I prefer to avoid that if at all possible. The solutions involves adding this method in
application_helper.rb
module ApplicationHelper
def url_for(options = nil)
if Hash === options
options[:protocol] ||= 'http'
end
super(options)
end
end
So my question is it possible to change this method or another one to change _path calls to explicit urls so I can use the above method to set the proper protocol.
you could try this, although I'm not 100% sure it works:
Use the proposed changes from the stackoverflow answer
Add this to application_controll.rb:
class ApplicationController < ActionController::Base
def url_options
{ :host => request.host }.merge(super)
end
end
According to the Docs it should add the full url even if you use _path:
:only_path - If true, returns the relative URL (omitting the protocol,
host name, and port) (true by default unless :host is specified).
My app requires that only a certain part of my site be SSL protected and the rest not.
That's your faulty assumption. The secure premise is that if some of your app requires SSL, then all of your app requires SSL. The correct assumption then is that your entire app requires SSL.
If your app requires SSL, then you should use something simple like rack-ssl which sets the HSTS header and enforces the secure flag on cookies in all responses.

renaming routes (map, link_to, to_param) in rails

I'm having a little issue...I setup a rails application that is to serve a german website. To make use of Rails' internal pluralization features, I kept all my models in english (e.g. the model "JobDescription").
Now, if I call "http://mysite.com/job_descriptions/", I get all my job_descriptions....so far, so good. Because I didn't want the english term "job_descriptions" in my url, I put the following into my routes.rb
map.german_term '/german_term', :controller => 'job_descriptions', :action => 'index'
map.german_term '/german_term/:id', :controller => 'job_descriptions', :action => 'show'
If I call "http://mysite.com/german_term/" or "http://mysite.com/german_term/283" I get all my job_descriptions, which is fine.
However, to make the URL more SEO friendly, I'd like to exchange the id for a more userfriendly slug in the URL. Thus, I put the following in my job_description.rb:
def to_param
"#{id}-#{name.gsub(/[^a-z0-9]+/i, '-')}"
end
which, whenever I use "job_description_path" in any link_to method, renders my URLs out to something like "http://mysite/job_descriptions/13-my-job-description-title".
However, and this is where I'm stuck, I'd like to get "http://mysite/german_term/13-my-job-description-title". I already tried to exchange the "job_description_path" with "german_term_path" in the link_to code, but that only generates "http://mysite/german_term/13". Obviously, to_param isn't called.
One workaround I found is to build the link with:
<%= link_to job_description.name, german_term_path(job_description.to_param) %>
But that's rather tedious to change all the link_to calls in my code. What I want is to replace "job_description" by "german_term" whenever it occurs in a URL.
Any thoughts?!?
Regards,
Sebastian
I think you're going to need to use the restful route helpers to get what you want.
In that case, it wouldn't take much re-factoring (assuming you've mapped JobDescriptions as a resource). Leave your to_param as is and change your JobDescriptions route to something like the following:
map.resources :job_descriptions, :as => 'german_term'
Hope this helps!
Rails only utilizes the
def to_params
end
URL builder when you are using a restful route/link helper. The only way I am aware of is to do it similar to how you did, unless you are willing to just scrap your english language links and do it all in German. In that case, just get rid of the named route lines and change the to_params to use the correct name field from the database. At that point, the REST routes should behave correctly.

Resources