I have a pretty standard rails 5.1 app which is mounted under a subdir under our main domain:
https://www.company.com/subir/
This is done in routes.rb
scope :subdir
the other routes
end
I use NGINX in our DMZ to pass incoming requests to my application server:
...
server_name www.company.com;
location /subdir {
proxy_pass https://my-app-server;
}
...
on my app-server is the pretty common combo Nginx/Puma installed and almost everything works fine, except the urls which are in the emails I send via actionmailer.
In my view I have a link:
link_to 'approve customer', admin_customer_url(#customer)
This creates the following:
https://www.company.com/**subdir/subdir**/admin/customer/:id
On my local machine these links are generated correctly in my emails, but not in staging environment on my app-server.
I dumped the request object in a view to see if my nginx setup is crazy but there is nothing obviously crazy...
Any ideas?
Check if you have config.action_mailer.default_url_options set in your environment file.
http://api.rubyonrails.org/classes/ActionMailer/Base.html
For the records: in deploy/staging.rb I still exported ENV['RAILS_RELATIVE_URL_ROOT']. This added the subdir twice to app.base_path and this was causing my issue.
Related
I find that when I run Rails 5 behind a reverse proxy, the default behaviour of url_for is use the host name of the upstream server, not the proxy itself.
For example, with nginx running at front.com and proxying requests to my upstream Rails server, which it knows as back, root_url returns http://back/.
If I tell nginx to pass the Host header as it proxies, root_url is http://front.com.
So far, so good. But I find using default_url_options in routes.rb (example below) does not have the power to override this. Why not? And if default_url_options can't override the Hostname from the request, what's the point of it?
Thanks!
EDIT
default_url_options example:
RoutingApp.routes.draw do
default_url_options host: 'example.com'
root to: 'pages#index'
end
(from this gist by a Rails core developer)
There are many places to set this, you set it for it to work under console, but not controller.
http://lulalala.logdown.com/posts/5835445-rails-many-default-url-options
I think you want it to work for controller/web view. Try this:
# production.rb
config.action_controller.default_url_options= {host: 'example.com'}
I'm trying register a service worker in Ruby On Rails to implement a push notification GCM. But nothing happens. Please, see my code below:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/assets/service-worker.js')
.then(initialiseState);
} else {
window.Demo.debug.log('Service workers aren\'t supported in this browser.');
This part works fine. But, when I call navigator.serviceWorker.ready.then(function(serviceWorkerRegistration), nothing happens.
I was searching on search engine and there are few things to help me.
Can anybody help me ?
Check out the serviceworker-rails gem.
As Jeff mentioned, the path on which the service worker must be "in scope". This gem allows you to proxy service worker requests at the root (or any other path) to a resource in the Rails asset pipeline.
For example, if your serviceworker script entry point is in app/assets/javascripts/nested/directory/serviceworker.js in your Rails project, you can configure your application to render the script from /serviceworker.js with some simple configuration setup:
# config/application.rb
config.serviceworker.routes.draw do
match "/serviceworker.js" => "nested/directory/serviceworker.js"
end
The service worker script, service-worker.js in your case, needs to be served from either the same-directory URL path as the page that's registering it, or a sub-path.
You're using the path /assets/service-worker.js, so unless the registering page is also served from /assets/, it's going to fail. If you put a .catch(function(error) { console.warn(error); }) at the end of your register() (which returns a Promise, you would see the error reported there.
The easiest thing to do is make sure that service-worker.js is served out of the same directory as the web page, and then call register('service-worker.js'), which uses a same-directory relative path.
My /blog directory is just a bunch of static HTML files. That's good.
When I go to localhost/blog it works fine - it renders the index.html for my middleman generated blog. Great.
But when I click on any of the posts, it gives me a routing error:
No route matches [GET] "/blog/2015/03/11/hello_world"
I am pretty sure the reason this is happening is because of one of these rules in my routes.rb:
get '/:friendly_id', to: 'posts#show'
get '/rbt/:name', to: redirect {|path_params, _| "/#{path_params[:name].gsub(/^\d+\-/, '')}" }
get ':name', to: 'posts#show'
I need all of these routes, but I don't want an HTML request to hit my Rack middleware unnecessarily....or worse yet, do a DB query which this error seems to suggest is happening.
How do I confine all requests to /blog/ to just resolve to my public/blog/ directory?
Edit 1
I realize the above description may not be clear. My Rails App isn't a blog, and so the posts you see referenced above, are not posts to the blog. They are posts of another kind, separately managed by the Rails app with a DB and all. I have since added a real /blog which will just be a collection of HTML articles generated by MiddleMan that will sit in my Rails /public/blog folder. The idea being that the HTML files in my /blog directory, should not hit my Rack middleware at all.
You can force rack to serve certain folder as static and routes-ignoring by adding config.middleware.use Rack::Static, urls: ['/blog'], root: 'public' to config/application.rb but imho it's better to setup a web server to intercept and serve /blog earlier than your app does.
And also in your case /blog/2015/03/11/hello_world seems to be a directory name, if you add index.html to the link it should work as you expect, without changing any configuration.
When your app is run by webserver, its webroot will be the public directory. So, if you have your blog directory inside public directory this should work. localhost/blog
Try running with nginx with following config :
root /root/path/to/your_app/public;
Couldn't you create a static_url controller and configure your routes so that
get '/blog', to: 'static_url#show'
Then in your controller have
def show
render file: request.fullpath
end
Sorry I can't test right now but I'm sure you get the idea. Also, I guess you would need to detect non-existent pages.
I just deployed one of my apps to heroku. This app uses :
A default "myapp.herokuapp.com" address,
And I got a domain configured so that the app can be reached through "www.myapp.com".
And I noticed today the following issue : my application links are based on "http://myapp.herokuapp.com" domain (hence I get "http://myapp.herokuapp.com/page" URLs) even when I access the app using my domain name (I would then expect to get "www.myapp.com/page" URLs).
I tried to edit my production.rb and set the default_url_options :
# Base domain for url generation
config.action_controller.default_url_options = { :host => "www.myapp.com" }
But it doesn't change a thing. Also tried to change this in application.rb, just in case, but nothing happens either.
Any clue ?
Thanks a lot for your help guys !
Edit : This used to work as expected before today when I did the database migration to the new Heroku postgres thing. Don't know if this can have any impact.
If you're using _path methods for your urls, this is generating a relative path which is always based on the url you visit. If you're using controller/fragment caching, you should probably use _url instead in your views. You might also want to consider setting config.action_controller.perform_caching to false in your production.rb if all your pages have some controller logic.
See this page for more info on how caching works in Rails.
I had a similar problem. It was caused by the following line of code which was pointing to heroku.com and getting redirected to herokuapp.com
config.action_mailer.default_url_options = { :host => 'my-staging-domain.heroku.com' }
I mention it because it's the action_mailer.default_url_options yet clearly it affects the default url options outside of the scope of the mailer if you haven't explicitly set up the action_controller.default_url_options
i want to send an email to user after he sign-up with code.for ex
http://192.168.1.51:3000/logins/activate/435546dgfd757676657 #link contains in an email
how can i create the above URL in my notifier model.
i know following way
url_for :controller=>'logins', :action=>'activate', :id=>'435546dgfd757676657' , :host=>'http://192.168.1.54:3000'
Which is working properly.
what i want that host should not be hard coded. How can i get host with port in a model.
In controller i can find it using follwing ways
request.host_with_port
Please provide me correct ruby way for doing same.
You can define the host in your environment.rb file.
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
As your host probably changes depending of your environment (development, test, production), it's better to put that config line inside the environment file.
After that, every link in emails will be made with that host. You don't have to provide it in the view anymore.