Rails 4 custom path helper - ruby

I would like to customize my path helpers in Rails 4.
I have a Site5 website (which uses Apache server) with multiple subdomains. I have rewrite rules in my .htaccess file which adds the folder name to the url. For example
cs1337.mysite.com/login
is rewritten to
cs1337.mysite.com/cs1337/login
In routes.rb, I have added a scope in routes.rb:
scope '/cs1337' do
get '/login', to: 'sessions#new', as: :login
# etc.
end
which gives me the correct routing. Everything works, but the annoying thing is that all my path helpers have the '/cs1337' prefix, which is unnecessary since the .htaccess rewrite rules add it back in. For example,
login_path # => /cs1337/login
when only
login_path # => /login
is necessary.
I would like to override all of the path helpers to strip off the prefix, using something like
def <override all path helpers>
path = super
path.gsub(%r{^/cs1337}, '')
end
I know the path helpers are dynamically generated, but I can't figure out where start ... I can't even find what module the path helpers are generated in.
Thanks for any help you can offer!

Short answer: No, as far as I can tell.
I couldn't find anything that lets you have the route Rails intercepts be different from the path that the helpers give you. I don't think Rails plays well with .htaccess rewrites.
Do you need the folder name to be in the path? If not, I would remove the scope '/cs1337' do and use something like this StackOverflow post to do domain-specific routes.
If you need it there, I would recommend being okay with the end user seeing "cs1337.mysite.com/cs1337/path".

Related

Sinatra: put some of my helpers in separate folder

I have a Sinatra app and I have some helpers and they have their folder (helpers) in which I have website_helpers.rb and so on. I want to move some of this helpers in their own folder inside the helpers folder: to have helpers/subhelpers, bacause the files I want to put in the subhelpers folder are different from the others and it makes sense to have a different folder for them.
I tried adding this to my config.ru
Dir.glob('./helpers/subhelpers/*.rb').each { |file| require file }
And then in the controller I have:
helpers MyHelperFromSubHelpers
but I get an error uninitialized constant (NameError).
Any ideas how to fix this so that to have a clear structure?
TBH, it sounds like you're overdoing it, there's always Rails if you want to go in for a more Java like every-namespace-must-be-a-directory layout. Aside from that, usually, helpers in separate files are placed in the Sinatra namespace - see http://www.sinatrarb.com/extensions.html#extending-the-request-context-with-sinatrahelpers
Personally, I put them in:
project-root/
lib/
sinatra/
name-of-extension.rb
Mainly because if the extension is really useful, I'll end up wanting to use it in another project, and this is the standard layout for a Sinatra gem, which makes it easy to extract it into one and with barely any change in the calling code.
Dir.glob will only return the file name and not the full path with each match, so you need to add the path:
Dir.glob('./helpers/subhelpers/*.rb').each do |file|
require File.expand_path File.join( File.dirname(__FILE__), "./helpers/subhelpers/", file)
end
will probably fix it.

No route matches [GET] "/"...Sometimes

So I'm a bit of a Rails n00b, so I'll apologize if this is really simple. When I access my server from another computer, I get this message:
No route matches [GET] "/"
And if I try to go to my subpages (Well, currently I only have one), I get something along these lines:
Unknown action
The action 'index' could not be found for AwebpageController
But here's the catch: this only happens sometimes. The rest of the time, the standard RoR homepage loads, and going to wwww.mydomain.com/awebpage serves up the page fine.
My Routes.rb looks like this:
Wobsite::Application.routes.draw do
resources :awebpage
end
And awebpage_controller.rb looks like this:
class AwebpageController < ApplicationController
end
And yes, index.html.erb for Awebpage does exist. It's all so simple that I don't understand what's going wrong. Oh, and my webserver is Thin (Not sure if that matters). Thanks in advance for any help!
You might want to add this to the top of your routes file to set the default controller and page for your site (i.e. http://www.mysite.com/):
root :to => "AwebpageController#index"
To remove the default Ruby on Rails webpage you'll also want to delete the index.html file in your /public/ directory.
Also, although not required, in your controller you're missing the function definition for index.
class AwebpageController < ApplicationController
def index
end
end
Normally you'd do application logic and serve up a view in this function; however if you do nothing RoR automatically loads the view associated with the page (index.html.erb).
If after all this you're still having a problem perhaps explicitly add index to the AwebpageController in your routes file; perhaps rails is only mapping www.mysite.com/Awebpage/ to Awebpage/index and not www.mysite.com/Awebpage/index.

Padrino, name route differently from path?

I want to be able to follow a convention closer to what Rails does with resourceful routing. For example, I'm considering "signups" to be a resource, with it's own controller containing "new" and "create" actions.
In app/controllers/signup.rb I have:
MyApp.controllers :signups do
get :index do
# ...
end
post :index do
# ...
end
end
Is there any way I can use these route names, while actually responding on a path other than '/signups'? It feels like Padrino's route naming system is very tightly coupled with the URLs the routes map to.
I've tried:
MyApp.controllers :signups, :map => '/another-path' do
# ...
end
Among various other things without success. Perhaps I should just go back to using Rails... I was just getting frustrated with the startup overhead in TDD and I'm embarking on a new project at the moment (please don't refer me to Spork... that has it's own issues).
This is how I would do what you are asking
# in app/controller/signups.rb
MyApp.controllers :'another-path' do
get '/' do
# ...
end
end

How can I create a Rails 3 route that will match all requests and direct to one resource / page?

I have a rails app (Rails 3.0) that I need to temporarily take out of service. While this is in effect, I want to create a new route that will direct all requests to a single piece of static content. I have a controller set up to serve my static pages.
I tried something like this:
match '*' => 'content#holding'
and
match '*/*' => 'content#holding'
to match a wildcard route as described here:Rails 3 route globbing without success.
This is probably a really simple answer, but I couldn't figure it out.
/EDIT/
Forgot to mention that I did have this rule at the very top of my routes.rb file.
Rails needs to bind the url parameters to a variable, try this:
match '*foo' => 'content#holding'
If you also want to match /, use parenthesis to specify that foo is optional:
match '(*foo)' => 'content#holding'
I did this just yesterday and first came up with the solution that klochner shows.
What I didn't like about this is the fact that whatever you enter in the URL, stays there after the page loads, and since I wanted a catch all route that redirects to my root_url, that wasn't very appealing.
What I came up with looks like this:
# in routes.rb
get '*ignore_me' => 'site#unknown_url'
# in SiteController
def unknown_url
redirect_to root_url
end
Remember to stick the routes entry at the very bottom of the file!
EDIT:
As Nick pointed out, you can also do the redirect directly in the routes file.
I ran into something like this where I had domain names as a parameter in my route:
match '/:domain_name/', :to => 'sitedetails#index', :domain_name => /.*/, :as =>'sitedetails'
The key piece to this was the /.*/ which was a wildcard for pretty much anything. So maybe you could do something like:
match '/:path/', :to => 'content#holding', :path=> /.*/, :as =>'whatever_you_want'
Where in "routes.rb" is this line located?
To have priority over other routes, it has to be placed first.
As an alternative, you can look into this: http://onehub.com/blog/posts/rails-maintenance-pages-done-right/
Or this: Rails: admin-only maintenance mode

Get absolute (base) url in sinatra

Right now, I do a
get '/' do
set :base_url, "#{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}"
# ...
haml :index
end
to be able to use options.base_url in the HAML index.haml.
But I am sure there is a far better, DRY, way of doing this. Yet I cannot see, nor find it. (I am new to Sinatra :))
Somehow, outside of get, I don't have request.env available, or so it seems. So putting it in an include did not work.
How do you get your base url?
You can get it using request.base_url too =D (take a look at rack/request.rb)
A couple things.
set is a class level method, which means you are modifying the whole app's state with each request
The above is a problem because potentially, the base url could be different on different requests eg http://foo.com and https://foo.com or if you have multiple domains pointed at the same app server using DNS
A better tactic might be to define a helper
helpers do
def base_url
#base_url ||= "#{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}"
end
end
If you need the base url outside of responding to queries(not in a get/post/put/delete block or a view), it would be better to set it manually somewhere.

Resources