I am trying to embed a downloadable file in rails. But getting the below error:
ActionView::Template::Error (undefined local variable or method `home_download_pdf_url' for #<#:0x007fd9f1a2eea0>):
home_controller.rb
def download_pdf
send_file(
"#{Rails.root}/public/Brochure.pdf",
filename: "Brochure.pdf",
type: "application/pdf"
)
end
routes.rb
get 'home/download_pdf'
view.html
<%= link_to 'Download Brochure', home_download_pdf_url>
I am new to Ruby. Please help.
Your using action as
download_pdf
so link to can be changed to
link_to "Download Brochure", controller: "home", action: "download_pdf"
If you're using an older Rails, make sure you restart the server after changing the routes. You might also try alternative route syntax get 'home/download_pdf' => 'home#download_pdf', run rake routes to make sure, you should see a line like home_download_pdf GET /home/download_pdf(.:format) home#download_pdf. You can probably also link directly to the file since it's in the public dir link_to 'Download Brochure', 'Brochure.pdf', and it's suspicious that your inspection of the view is #<#:0x007fd9f1a2eea0>, been a while since I looked at rails, but I'd expect it to have a class name there. Usually view files are view.html.erb, not view.html, and that file name name is a bit suspicious, what's the full path to the file from the rails root? I'm expecting something like app/views/home/index.html.erb usually the filename will be in a dir named after the controller (hence home), and the file will be named after the action (controller method that rendered it). There are deviations from these conventions, but I can't tell if yours is one of them.
The error is simple, it means you don't have a route defined with the "name" that you're referencing:
#config/routes.rb
get "home/download_pdf", to: "home#download_pdf", as: :home_download_pdf
#app/controllers/home_controller.rb
class HomeController < ApplicationController
def download_pdf
# ...
end
end
#app/views/home/download_pdf.html.erb
<%= 'Download Brochure', home_download_pdf_path %>
As a tip, we always put "misc" actions in our ApplicationController:
#config/routes.rb
get "download_pdf", to: "application#download_pdf", as: :home_download_pdf
#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def download_pdf
# ...
end
end
--
If you have to use a home controller etc, you'll mostly want to embed any extra routes into a resources directive:
#config/routes.rb
resources :home, only: [] do
get :home_download_pdf, on: :collection #-> url.com/home/home_download_pdf
end
Related
while trying to familiarize with using resources for planning routes,
I encountered a weird error:
No template for interactive request
ShoppersController#index is missing a template for request formats: text/html
Here are the routes mapping
routes.rb
Rails.application.routes.draw do
resources :shoppers
end
shoppers_controller.rb
class ShoppersController < ApplicationController
def index
end
def create
#shopper = Shopper.new
end
end
shoppers.html.erb
<h1>Welcome Shoppers</h1>
Does anyone know how to solve this?
Thanks for all the feedbacks you share.
It's because the name of your view is wrong. As the error you're getting says: 'Rails expects an action to render a template with the same name contained in a folder named after its controller'
So in your case, the structure needs to be:
app
controllers
shoppers_controller.rb
views
shoppers
index.html.erb
new.html.erb
Reference: https://guides.rubyonrails.org/layouts_and_rendering.html#rendering-by-default-convention-over-configuration-in-action
Create a view with the name of the action in the controller!
Apologies for the basic question, but I'm trying to create an endpoint so I can a TranslationApi in my backend via my VueJs frontend via Fetch, so I need to make an endpoint I can insert. I'm attempting to create a route to make that happen, however when I run bin/rails routes | grep CcApiController I receive the following error:
ArgumentError: 'CcApiController' is not a supported controller name. This can lead to potential routing problems. See http://guides.rubyonrails.org/routing.html#specifying-a-controller-to-use
I've read the documentation linked, but I'm not managing to fix this, can someone explain where I'm going wrong here? I'll link the files I've changed below:
cc_apis_controller.rb
module Panel
class CcApisController < CcenterBaseController
def index
run Ccenter::Adapters::Zendesk::TranslationApi.call(2116449)
end
end
end
panel_routes.rb
def draw_api_routes
resources: CcApiController
end
routes.rb
Rails.application.routes.draw do
resources :CcApiController, only: [:index]
end
API method I need to create Route for:
def make_request
response = Faraday.post('https://api.deepl.com/v2/translate', auth_key: '', text: #final_ticket, target_lang: 'DE', source_lang: 'EN')
if response.status == 200
body = response.body
message_element = body.split('"')[-2]
return message_element
else
raise InvalidResponseError unless response.success?
end
end
The answer to that is pretty simple.
Route names are snake_case, and match the controller's file name just omit the _controller suffix. In your case it is
Rails.application.routes.draw do
namespace :panel do
resources :cc_apis, only: %i[index]
end
end
For more info check this documentation and this article.
I have seen the few links on here regarding this topic but as yet have been unable to crack the problem. I want my application to allow users to register but also to register other users. So far my code lucks like so (though at this point I'm not sure I'm even on the right path and have probably included stuff which is not required just to make it work):
routes.rb
resources :devise
devise_for :users, path: 'devise'
devise_scope :user do
get 'users/registrations/admin_new' => 'devise/registrations#admin_new'
post 'users/registrations/admin_create' => 'devise/registrations#admin_create'
end
These are the two methods I have referenced in my route.
controllers/user/registration_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
def admin_new
puts "---------------"
#user = User.new
end
def admin_create
puts "---------------"
end
end
My view is as follows but shortened so as not to include all the fields:
views/devise/registrations/admin_new.html.haml
= simple_form_for(User.new, url: users_registrations_admin_create_path(User.new)) do |f|
...
This set up has gotten me to the point that the url:
http://localhost:3000/users/registrations/admin_new
loads the form alright however the puts I inserted does not appear in my console when it loads which is strange. Also i previously had the form as:
= simple_form_for(#user, url: users_registrations_admin_create_path(#user)) do |f|
...
however this resulted in the error:
undefined method `model_name' for nil:NilClass
which is why I changed to User.new instead of #user. When i submit the form it returns the error:
The action 'admin_create' could not be found for Devise::RegistrationsController
I'm at a loss as to why this is. I'm also unsure as to whether the structure of my devise is correct given the controllers are contained within a users folder while the views are contained with a devise folder. Any help on this would be greatly appreciated.
your route is problem.
post 'users/registrations/admin_create' => 'devise/registrations#admin_create'
which means this route to admin_create action in Devise::RegistrationsController
so router find a action in Devise::RegistrationsController but action "admin_create" exists in Users::RegistrationsController,
change
'devise/registrations#admin_create'
=> 'user/registrations#admin_create'
update1
I check your route out.
assigned route path to controller in 'controllers/devise/registrations_controller.rb'
post 'users/registrations/admin_create' => 'devise/registrations#admin_create'
PREFIX users_registrations_admin_create
URL PATTERN /users/registrations/admin_create(.:format)
Controller&Action devise/registrations#admin_create
assigned route path to controller in 'controllers/user/registrations_controller.rb'
post 'users/registrations/admin_create' => 'user/registrations#admin_create'
PREFIX users_registrations_admin_create
URL PATTERN /users/registrations/admin_create(.:format)
Controller&Action user/registrations#admin_create
only 'devise' controller name changed to 'user' in route, then fine.
I'm writing a little Rails CMS and I'm a little stuck with a routing error. To begin with, I have a basic model called Entry, which other models are inheriting from. When I try to edit an existing model, it returns me an error
No route matches [PATCH] "/admin/posts/entries"
In my routes.rb in CMS plugin I have the following:
Multiflora::Engine.routes.draw do
root "dashboard#index"
scope "/:content_class" do
resources :entries
end
end
and in test app's routes.rb I have
mount Multiflora::Engine, at: '/admin'
In application_controller.rb I also tweaked routes a little:
def content_entries_path
entries_path(content_class: content_class.tableize)
end
helper_method :content_entries_path
def content_entry_path(entry)
entry_path(entry, content_class: content_class.tableize)
end
helper_method :content_entry_path
def new_content_entry_path
new_entry_path(content_class: content_class.tableize)
end
helper_method :new_content_entry_path
def edit_content_entry_path(entry)
edit_entry_path(entry, content_class: content_class.tableize)
end
helper_method :edit_content_entry_path
And in my show.html.erb I have this:
<%= link_to 'Edit', edit_content_entry_path(#entry) %>
When I navigate to edit_content_entry_path, it shows me edit page correctly, but when I try to save edited entry, it returns me an error stated above. When I run rake routes, it returns me the following:
entries GET /:content_class/entries(.:format) multiflora/entries#index
POST /:content_class/entries(.:format) multiflora/entries#create
new_entry GET /:content_class/entries/new(.:format) multiflora/entries#new
edit_entry GET /:content_class/entries/:id/edit(.:format) multiflora/entries#edit
entry GET /:content_class/entries/:id(.:format) multiflora/entries#show
PATCH /:content_class/entries/:id(.:format) multiflora/entries#update
PUT /:content_class/entries/:id(.:format) multiflora/entries#update
DELETE /:content_class/entries/:id(.:format) multiflora/entries#destroy
So, the error was in my edit.html.erb view -- instead of
<%= form_for(#entry, as: :entry, url: content_entry_path(#entry)) do |f| %>
I had
<%= form_for(#entry, as: :entry, url: entries_path do |f| %>
When I rewrote it, everything worked!
In my rails application I add an "api" area with controllers
In the route.rb file
I add the area
namespace :api do
#get "dashboard/sales_rate"
end
The controllers Class:
class Api::DashboardController < Api::ApplicationController
before_filter :authenticate_user!
def user_service
render :json => {"user_id" => current_user.id}
end
The Path is:
app/controllers/api/dashboard_controller
My question is if I can that the route take all action
for example /api/dashboard/user_service
and I will not add for each route row on the route.rb page
/api/{controller_under_api_namespace}/{action}
You can do with some meta programming sprinkle!
Api.constants.each |c|
c.action_methods.each do |action|
get [c.controller_name, action].join('/')
end
end
This method limits only to GET request. You can overcome it with RESTful routing.
Api.constants.each |c|
resources c.controller_name.to_sym
end
Hope, that helps. :)
I try add the code on the route.rb file
and I got this error
This is my file
But before trying to fix this part of code, I want to know if it's can change the performance or the calls to those pages?
If it not good for the performance I leave this option.