I'm trying to export a docx file using caracal but I'm getting a routing error, but everything seems to be okay.
I did this 3 days ago exactly like now and worked, now I'm getting an error.
Routes.rb
Rails.application.routes.draw do
get 'grayscale/index'
devise_for :users, path: '', path_names: {sign_in: 'login', sign_out: 'logout', sign_up: 'registrar'}
resources :contratos
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root 'contratos#index'
get 'contratos/page'
end
contratos_controller.rb
class ContratosController < ApplicationController
before_action :authenticate_user!
before_action :set_contrato, only: [:show, :edit, :update, :destroy, :export, :page]
access all: [:show, :index], user: {except: [:destroy, :new, :create, :update, :edit]}, site_admin: :all
require './lib/generate_pdf'
# GET /contratos
# GET /contratos.json
def index
#contratos = Contrato.all
end
# GET /contratos/1
# GET /contratos/1.json
def show
end
# GET /contratos/new
def new
#contrato = Contrato.new
end
# GET /contratos/1/edit
def edit
end
def page
Caracal::Document.save(Rails.root.join("public", "example.docx")) do |docx|
# page 1
docx.h1 'Page 1 Header'
docx.hr
docx.p
docx.h2 'Section 1'
docx.p 'Lorem ipsum dolor....'
docx.p
end
path = File.join(Rails.root, "public")
send_file(File.join(path, "example.docx")
end
show.html.erb
<%= link_to 'Generate Docx', contratos_page_path %>
The full error
ActiveRecord::RecordNotFound in ContratosController#show
Couldn't find Contrato with 'id'=page
def set_contrato
#contrato = Contrato.find(params[:id])
end
This is a very common beginner issue which is due to the fact that routes have precedence in the order they are declared (thus the comment on top of routes.rb).
Since resources :contratos already defines a GET /contratos/:id route it will always match the request for GET /contratos/page to contratos#show. Rails does not assume that your ids are numerical when routing. These paths will all match the GET /contratos/:id route:
GET /contratos/1
GET /contratos/page
GET /contratos/page?foo=bar
GET /contratos/foo-bar-baz
GET /contratos/alksjd-usfiugi%-dfgd
But these will not:
GET /contratos/new # declared before the show route
GET /contratos/1/foo
GET /contratos/foo/bar
You can fix this by moving your custom route to the top:
get 'contratos/page'
resources :contratos
But there is a better Rails way of adding additional restful actions to a resource:
resources :contratos do
get :page, on: :collection
end
Related
I am getting this error:
StaticController#home is missing a template for request formats: text/html
This is my controller:
class StaticController < ApplicationController
def home
# render json: {status: "is working"}
end
end
When I uncomment the comment above, it renders that.
my views/static/home.html.erb view:
<%= javascript_pack_tag 'index' %>
and my routes:
Rails.application.routes.draw do
resources :sessions, only: [:create]
resources :signup, only: [:create]
delete :logout, to: 'sessions#logout'
get :logged_in, to: 'sessions#logged_in'
root to: "static#home"
# get '*path', to: "static#home", via: :all
end
I'm using Rails 5 and my routes look something like:
Rails.application.routes.draw do
namespace :admin do
namespace :moderation do
resources :templates
end
resources :users, except: [:new, :create] do
namespace :moderation do
resources :messages, only: [:index, :show, :new, :create, :update, :edit] do
resources :message_replies, only: [:create, :edit, :update]
end
resources :templates
end
end
root "home#index"
end
end
I have models/admin/user.rb:
module Admin
class User < ::User
end
end
And models/admin/moderation/template.rb:
module Admin
module Moderation
class Template < ::Moderation::Template
end
end
end
Now when I try to generate the right route using url_for helper:
2.4.1 (main):0 > admin_user = Admin::User.first
2.4.1 (main):0 > admin_moderation_template = Admin::Moderation::Template.first
2.4.1 (main):0 > url_for([admin_user, admin_moderation_template])
NoMethodError: undefined method `admin_user_admin_moderation_template_url' for main:Object
Instead of getting admin_user_moderation_template_url I got admin_user_admin_moderation_template_url. Any help of how should I generate the right route in this case?
I wonder if you could resolve using this xxx_url() helper. In your case it'd be:
admin_user_moderation_template_url( user_id: admin_user.id, id: admin_moderation_template.id )
.
EDIT
Unfortunately I cannot try it as I would have to build the app you are working on. But as stated in this answer you can use symbols to create admin_user_moderation_template_url.
Try to run the following line and tell me if it works (I'm not sure user_id is in the right position, but it might work).
url_for( [:admin, :user, :moderation, :template, user_id: admin_user.id, id: admin_moderation_template.id ])
You need also an association between User and Template to be able to link them.
I'm getting this error.When I want to run te server on localhost:3000/api/v1/songs.json
Routing Error
uninitialized constant API::V1::SongsController.
Thats my routes.rb file:
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :songs, only: [:index, :create, :update, :destroy]
end
end # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Routes
Routes match in priority from top to bottom
Helper HTTP Verb Path Controller#Action
Path / Url
Path Match
api_v1_songs_path GET /api/v1/songs(.:format)
api/v1/songs#index
POST /api/v1/songs(.:format)
api/v1/songs#create
api_v1_song_path PATCH /api/v1/songs/:id(.:format)
api/v1/songs#update
PUT /api/v1/songs/:id(.:format)
api/v1/songs#update
DELETE /api/v1/songs/:id(.:format)
api/v1/songs#destroy
and thats my SongsController:
class Api::V1::SongsController < Api::V1::BaseController
def index
respond_with Song.all
end
def create
respond_with :api, :v1, Song.create(song_params)
end
def destroy
respond_with Song.destroy(params[:id])
end
def update
song = Song.find(params["id"])
song.update_attributes(song_params)
respond_with song, json: song
end
private
def song_params
params.require(:song).permit(:id, :name, :singer_name, :genre, :updated_at, :tag)
end
end
I'm going to copy how we have this running, cause I cannot see a direct difference between your code and our code....
routes.rb
constraints subdomain: Settings.subdomains.api do # you can ignore this
namespace :api do
namespace :v1 do
resources :maps, only: [] do
collection do
get :world_map
end
end
end
end
maps_controller.rb
module Api
module V1
class MapsController < BaseController
def world_map; end
end
end
end
routes output
world_map_api_v1_maps GET /v1/maps/world_map(.:format) api/v1/maps#world_map {:subdomain=>"api"}
The spelling is really crucial from what I can see.
The directort structure for us:
app/controllers/api/v1/maps_controller.rb
So check those points and this should work because it's standard Rails magic.
I am trying to get a delete button to work using a piece of code I have written within my tags_controller page;
def destroy
#tag = Tag.find(params[:id])
#tag.destroy
redirect_to :back, notice: 'Tag was successfully deleted!'
end
When I run from my local host, it throws an exception as shown below;
Routing Error
No route matches [DELETE] "/admin/tags/37/edit"
Rails.root: /Users/laurenwoodhams/Desktop/PROJECT/RAILS-BLOG/-t
Here is my config routes;
Rails.application.routes.draw do
get '/login' => 'admin/sessions#new'
get '/logout' => 'admin/sessions#destroy'
namespace :admin do
resources :posts
resources :tags, except: [:index]
resources :sessions, only: [:new, :create, :destroy]
resources :administrators, only: [:index, :edit, :update]
end
end
Could you please examine and explain why this may be occurring?
Thank you
DELETE is the HTTP verb (like GET or POST) which means..
To make a link to delete your tag you'll need to do something like this in your view.
<%= link_to "Delete Tag", #tag, method: "delete" %>
Then it should work properly.
P.S.
You can run bin/rake routes to see your routes.
Rspec fails with ActionController::UrlGenerationError with a URL I would think is valid. I've tried messing with the params of Rspec request, as well as fiddled with the routes.rb, but I'm still missing something.
The weird thing is, it works 100% as expected when testing locally with curl.
Error:
Failure/Error: get :index, {username: #user.username}
ActionController::UrlGenerationError:
No route matches {:action=>"index", :controller=>"api/v1/users/devices", :username=>"isac_mayer"}
Relevant code:
spec/api/v1/users/devices_controller_spec.rb
require 'rails_helper'
RSpec.describe Api::V1::Users::DevicesController, type: :controller do
before do
#user = FactoryGirl::create :user
#device = FactoryGirl::create :device
#user.devices << #device
#user.save!
end
describe "GET" do
it "should GET a list of devices of a specific user" do
get :index, {username: #user.username} # <= Fails here, regardless of params. (Using FriendlyId by the way)
# expect..
end
end
end
app/controllers/api/v1/users/devices_controller.rb
class Api::V1::Users::DevicesController < Api::ApiController
respond_to :json
before_action :authenticate, :check_user_approved_developer
def index
respond_with #user.devices.select(:id, :name)
end
end
config/routes.rb
namespace :api, path: '', constraints: {subdomain: 'api'}, defaults: {format: 'json'} do
namespace :v1 do
resources :checkins, only: [:create]
resources :users do
resources :approvals, only: [:create], module: :users
resources :devices, only: [:index, :show], module: :users
end
end
end
Relevant line from rake routes
api_v1_user_devices GET /v1/users/:user_id/devices(.:format) api/v1/users/devices#index {:format=>"json", :subdomain=>"api"}
The index action requires a :user_id parameter, but you haven't supplied one in the params hash. Try:
get :index, user_id: #user.id
The error message is a bit confusing, because you aren't actually supplying a URL; instead you are calling the #get method on the test controller, and passing it a list of arguments, the first one is the action (:index), and the second is the params hash.
Controller specs are unit tests for controller actions, and they expect that the request parameters are correctly specified. Routing is not the responsibility of the controller; if you want to verify that a particular URL is routed to the right controller action (since as you mention, you are using friendly-id), you may want to consider a routing spec.