I have a route that is triggered when someone clicks a hyperlink to download a file.
My routes:
'/document/download_some_file/' => 'documents#download_some_file'
My controller:
def download_some_file
content = 'hello world'
send_data content, :filename => 'some_file.dat'
# if I comment out the above line (send_data) I get a missing template error
# if I name this function anything other than download_xyz I get a missing template error
end
This works fine. However I have another hyperlink:
'/document/refresh_files/' => 'documents#refresh_files'
then
def refresh_files
#stuff here
#this throws a missing template error
#if I rename this to download_xyz it works fine
end
So...what's going on here exactly? The first function I showed (download_some_file) does work properly.
The refresh_files is what I'm trying to fix. It should just call another function inside the Documents controller. Even if I just do a puts I get a template error.
It depends on what you are doing with the route. Since you are sending a file in the download_some_file method, it does not require a template.
For refresh_files I am assuming you are not trying to send a file, but maybe refresh a list. Maybe you want javascript back. This will require a template named refresh_file.js.erb that lives in your app/views/documents folder. Any format that you are requesting will probably end up needing a template besides maybe json if you send it from the method itself, but you could build a template for that too.
Once you have a template that you want back from the controller in your folder that goes with your method, you will be able to respond to it
You need to have corresponding template in view called refresh_files.html.erb Controller method searches template with corresponding name.
Related
I have the following routes:
create_admin_path GET /app/views/createAdmin/create_admin.html.erb(.:format) application#createAdmin
I have this in routes.rb
get "/app/views/createAdmin/create_admin.html.erb", to: "application#createAdmin", as: "create_admin"
I have this in the application_controller.rb
def createAdmin
end
and in the view I have a folder called createAdmin which has a file called create_admin.html.erb
in the create_admin.html.erb I have something like this:
<h1> testing is here </h1>
Yet I am receiving this error message:
No route matches [GET] "/app/views/create_admin/create_admin.html.erb"
What am I doing wrong ?
Thanks for your time
The views must match in controller name and view file name, that's if you're registering the route to application#createAdmin, then the folder must be application/ and the file createAdmin, in camel case as you've named the action and the route, so your file must be called createAdmin and must be located in a folder called application/.
/app/views/application/createAdmin.html.erb.
But, there are some things to add:
There's no need to use the ApplicationController to handle such operations, you can easily create a new controller and use it with that purpose instead polluting the ApplicationController.
You don't need to specify the full route to the view as the URI when registering a route, unless it's that specifically what want to do.
When working with Ruby use snake case.
I wonder where those controller default actions defined. Even though I do not write the index action, the index view could be render! I used to read rails source code, but I can get where the method declares. I guess the actions is known by rails by the routes.rb . Anyone knows where I can find them in rails source code.
You could see in rails/actionpack/lib/action_controller/metal/implicit_render.rb
def method_for_action(action_name)
super || if template_exists?(action_name.to_s, _prefixes)
"default_render"
end
end
Rails will call default render when there is template even without you define action name.
I am new to Ruby on Rails and am trying to gain a strong understanding of how MVC works.
I did the following:
rails new bubblesman
rails generate controller bubble
in my bubble controller I created a method as follows:
def available
puts "YEP!!!!!!"
end
I put the following in my routes file:
'welcome' => 'bubble#available'
I navigate to http://localhost:3000/welcome
I get the below error:
ActionController::UnknownFormat (BubbleController#available is missing a template for this request format and variant.
request.formats: ["text/html"]
request.variant: []
NOTE! For XHR/Ajax or API requests, this action would normally respond with 204 No Content: an empty white screen. Since you're loading it in a web browser, we assume that you expected to actually render a template, not… nothing, so we're showing an error to be extra-clear. If you expect 204 No Content, carry on. That's what you'll get from an XHR or API request. Give it a shot.):
what I also don't understand is if I put this in my helper controller instead of my main controller it all works fine.
you need to create the available.html.erb file within the views/bubble/ directory. When the route takes you to that action, it also navigates you to that view, so if you put:
<h2>YEP!!!!</h2>
as the only line in that file, it should return that to you on the webpage.
In the future, you could use rails g scaffold bubbles and that will create a majority of the files (MVC) and routes for you.
Directory:
Prototype
-app
-assets
-controllers
---welcome_controller.rb
domainobjects
---SimilarJob.rb
Utilities
--API.rb
Controller Code
require_relative '../domainobjects/SimilarJob'
class WelcomeController < ApplicationController
def index
foo = API.new('DEVKEY')
res = foo.RetrieveFacts("Test", "Me")
#newResult = SimilarJob.new("test") <-- Failing Line!!!
render :text => res["Response"]["IsInternationalResponse"]
end
end
Object Code
class SimilarJob
end
I stripped out some things, but the API class exists in a separate directory, "Utilities", and for some reason I don't even have to reference it using the "requires_relative" keyword. It's a wrapper class that includes HTTParty and makes a successful GET request to my external API every time. Can someone explain why I seemingly don't have to reference it anywhere?
Alternatively, attempting to initialize the SimilarJob class fails each time. The error is:
uninitialized constant WelcomeController::SimilarJob
From what I researched here and on the web, this means I'm not referencing the file correctly. To test this out, I tried naming it incorrectly in the "requires_relative" statement and the framework informs me that the requested file could not be loaded. So it seems like Rails is finding my class, it just won't initialize it for some reason.
The most maddening part is that I'll make a few small changes to SimilarJob, restart my server, and it'll work all of a sudden. If I stop and start the server again, it's back to the error I pasted below.
This is my first time really digging in something other than .NET MVC or KnockoutJS..would you guys mind pointing out the error of my ways?
EDIT: I used the generate command for this controller, so all views and routes work appropriately. In fact, if I comment out the problematic line, the property I'm referencing on the last line in my JSON response renders to the file just fine.
EDIT v2: Strangely enough..changing my class name to Jobs (one word) is getting rid of this error. This comes off as bizarre! Can anyone confirm that this is my issue?
Names matter, and you've named your file wrong. SimilarJob.rb needs to be similar_job.rb.
Similarly, your API file should be called api.rb, and the class it defines should be called Api. This stuff is important, as you've deviated badly from Rails convention, and are suffering for it.
I added format.js to my controller, yet I still cannot get the js in index.js.erb to execute when I view my index page. The only thing I can figure out is that it must be because of the model name. I had to add
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'business', 'businesses'
end
to my inflections.rb file...because my model is called Business.
my views/js are located at views/businesses/*
Please help before I pull my hair out!
All I have in the index.js.erb file is:
alert(1);
Obviously the goal is that I will get an alert when I finally get the issue fixed, letting me know it is working.
How are you calling your index page? If you visit the index page from your your browser it won't render index.js. That's the whole point behind using format. You will have to call your index method using javascript(something like an ajax call). Your model name does not have anything to do with it.
Javascript execution has nothing to do with your model names. Nor is the inclusion of your JS files done based on the name of the controller or model. If you are using the asset pipeline you need the following.
Assuming that index.js is in /assets/javascripts/index.js, add the following to the /app/assets/javascripts/application.js
//= require ./index
If you don't understand how this works, you may wish to go through the Ruby on Rails Guide for the Asset Pipeline, found here: http://guides.rubyonrails.org/asset_pipeline.html
As a side note, with your inflections usage, I would recommend that if you are going to use a framework like Rails, try and use conventions that come with it. It will save you heartache in future. Name your model business so that your table is called businesses. Unless you really want something like this:
has_one :businesses