In a Rails and Ember project, I decided to use EmberCLI Rails because I want to do integration tests with Capybara and all my favorite testing gems.
I installed it and it works when I go to the home page.
I added routes on ember like this :
import Ember from 'ember'
import config from './config/environment'
Router = Ember.Router.extend(location: config.locationType)
Router.map ->
#resource 'users'
export default Router
When I go on http://localhost:3000/users, I have a no route matches error. I understand why this is happening, Rails does not load routes of embers. Is there a solution to do it or is it just impossible with EmberCli-Rails for now?
Your Rails app needs a wildcard route so it knows to handle those requests through your Ember app controller. Can you try adding a route in routes.rb:
get '/:all', to: "ember#index"
substituting ember#index with whatever you have set up as the controller and action for your Ember app.
Related
I'm working on a project where I have a Rails application (rails 4.2.5) that incorporates a gem, which is a Rails Engine. I'm currently working on moving the route definitions from the main application to the gem. I have a controller test that exercises one of the routes. The test fails when I move the route definition over to the gem, but the route looks the same.
My gem is called CallCenter, and includes a controller called call_center_controller (with an action called reports_tab). This is what routes.rb looks like in the Rails app:
...
mount CallCenter::Engine, at: "/call_center", as: 'call_center_urls'
get '/call_center/reports_tab' => 'call_center/call_center#reports_tab'
...
This is what I get running rake routes:
❯❯❯ rake routes | grep reports_tab
call_center_reports_tab GET /call_center/reports_tab(.:format) call_center/call_center#reports_tab
At this point controller test runs without errors. But when I move the route definition to the routes.rb file in the gem:
get 'call_center/reports_tab' => 'call_center#reports_tab'
(note that the route now points to 'call_center#reports_tab' instead of 'call_center/call_center#reports_tab', because the main application mounts the engine at /call_center)
Here is my output from rake routes, (still running from the main app's directory)
❯❯❯ rake routes | grep reports_tab
call_center_reports_tab GET /call_center/reports_tab(.:format) call_center/call_center#reports_tab
This is identical to the route reported by rake routes when it was defined in the main app, but now my test fails with the following message:
Failure/Error: get :reports_tab
ActionController::UrlGenerationError:
No route matches {:action=>"reports_tab", :controller=>"call_center/call_center"}
As far as I can tell the route is defined, and looks exactly the same as it did before when it was in the routes file for the main app. What am I missing?
I found the answer - I needed to add this to my controller spec to tell it to look at the routes provided by the Engine:
routes { CallCenter::Engine.routes }
I'm currently working on a application with a Ruby on Rails backend and Vue.js frontend. It's a single page application. I'm using the webpacker gem to build my main JS file.
I've added vue-router and and a couple frontend routes. I'm able to navigate using <router-link> which correctly renders the appropriate component. What I can't figure out is how do I setup my frontend routes so that someone can directly navigate to a URL without hitting my Rails routes.
For example if I type /sample-route I'd like to hit my Vue.js route and not my Rails route. I still want to be able to make API calls to my Rails routes as well. For example /api/users.
My problem was solved by adding <router-view></router-vew> into my main Vue.js component.
Here's my rails routes file as well:
Rails.application.routes.draw do
namespace :api do
# api routes here
end
root 'application#index'
get '/*path', to: 'application#index'
end
Depending on how many routes you have, you can add your Vue routes to routes.rb and send them to your root Vue application route. e.g. Webpacker is rendering your js pack with controller#action vue_controller#app. Your Vue app router uses /user/profile. In routes.rb, add a route:
get "/user/profile" => "vue_controller#app" # <- The controller action rendering your Vue pack
If it seems unmaintainable to redefine every Vue route in routes.rb, you may want to look into a universal fallback route that sends them to the vue app controller action. As long as you don't change the route, but just respond with the Vue controller action, the Vue router will take care of rendering the right components for that route when the page loads.
In Rails 4, you can use something like the answers in this SO question to help you out with setting up a "catch-all" route Rails catch-all route.
EDIT: Using a catch all route does lead to some problems with 404's. If the user requests a route that doesn't exist, the Rails app will still send them the Vue pack. To fix this, you would need to add some unknown route handling in your Vue router to render something like a 404 page.
There is one more approach which will be useful and handles sub-routes as well (having separate vue apps per page in a single rails app):
routes.rb
Rails.application.routes.draw do
# this route entry will take care of forwarding all the page/* urls to the index
get 'page_controller/*path', to: 'page_controller#index', format: false
end
Additionally, please handle the api and index routes separately based on the design.
vue-routes.js
const router = new VueRouter({
mode: 'history',
base: '/page_url',
routes: [
...
]
});
I changed the structure of my Ruby on Rails app, I want the 'app' folder to be inside a backend folder. in config/routes.rb I have this:
get '/', controller:'../backend/app/controllers/static_pages_controller#root'
But when I start the server it give the error :
'../backend/app/controllers/static_pages_controller#root' is not a supported controller name.
How can I do this?
There is no need to write full-path. You should know about convention over configuration, that is the major idea about Ruby on Rails.
so,
root 'static_pages_controller#index'will be find.
if the backend is namespace,
namespace :backend, path: '/' do
root 'static_pages_controller#index'
end
I'm playing around with a tester app using an ember frontend and using jsonapi-resources to build the rails api. My routes in the rails app are defined as follows
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
jsonapi_resources :books
jsonapi_resources :authors
jsonapi_resources :publishing_houses
end
However I've noticed something strange. If I go to the path for publishing_houses like so: http://localhost:3000/publishing_houses it says the route/page doesn't exist. However if I go to http://localhost:3000/publishing-houses with a dash instead of an underscore between publishing houses, I get the response that I want.
The problem is in my ember app, I've checked the console and it requests data using this url: http://localhost:3000/publishing_houses with the underscore, so I don't get any data back in my ember request.
Is there a reason for this behavior? Or am I doing something wrong?
I did some digging and there appears to be a config for the route format. Try this
# config/initializers/jsonapi.rb
JSONAPI.configure do |config|
config.route_format = :underscored_route
end
That should turn the routes into "/publishing_houses" instead of "publishing-houses" which would make them compatible with the other library you are using.
I feel like this should not be all that difficult, but I cannot find any solutions that seem to work with Rails4
My setup
I have a proxy server (Kong) that directs to various services behind it based on path.
myapp.com/app1/ is redirected to http://app1_address:PORT/ (notice /app1 is stripped)
same for myapp.com/app2
app2 is a Rails 4 application and it works just fine when browsing to specific, but its relative routing is completely off. For example, link_to or url_for links to controllers or actions all redirect to the wrong links.
For example, I have a logout link that has a path of /logout on app2, but redirecting the user to /logout is incorrect. They need to be routed to /app2/logout. How can I configure the Rails app to add a prefix to all routes?
I have tried:
config.action_controller.relative_url_root = '/app2'
As well as this:
config.relative_url_root = '/app2'
And this in config.ru
map <MyAppName>::Application.config.relative_url_root || "/" do
run Rails.application
end
Any ideas for how to make this work?
You should use a scope in your routes:
Rails.application.routes.draw do
scope ENV["PROXY_PATH"] do
# your routes..
end
end
This way you'll have to set the ENV variable:
$ export PROXY_PATH=app2
$ bin/rails s