Rails 5 is ignoring view templates - ruby-on-rails

In my Rails project, I ran:
rails generate scaffold car
which successfully created all of the necessary files and directories for the application. This includes the standard application.html.erb layout file, as well as the app/views/cars directory that includes more standard html.erb files (index, show, ETC.)
In addition, my cars route is in place in config/routes.rb.
My next command is rails server, which is also successful.
When I open my browser and go to localhost:3000, the welcome page for ruby on rails pops up as normal. I'm expecting that when I go to localhost:3000/cars, I'll see the html rendered from app/views/cars/index.html.erb. If not, I at least expect that it will default to application.html.erb.
Instead, I am repeatedly receiving the following:
>ActionController::UnknownFormat in CarsController#index
>CarsController#index is missing a template for this request format and variant. request.formats: ["text/html"] request.variant: []
My controller class looks like this:
class CarsController < ApplicationController
before_action :set_car, only: [:show, :edit, :update, :destroy]
# GET /cars
# GET /cars.json
def index
#cars = Car.all
end
# GET /cars/1
# GET /cars/1.json
def show
end
# GET /cars/new
def new
#car = Car.new
end
# GET /cars/1/edit
def edit
end
# POST /cars
# POST /cars.json
def create
#car = Car.new(car_params)
respond_to do |format|
if #car.save
format.html { redirect_to #car, notice: 'Car was successfully created.' }
format.json { render :show, status: :created, location: #car }
else
format.html { render :new }
format.json { render json: #car.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /cars/1
# PATCH/PUT /cars/1.json
def update
respond_to do |format|
if #car.update(car_params)
format.html { redirect_to #car, notice: 'Car was successfully updated.' }
format.json { render :show, status: :ok, location: #car }
else
format.html { render :edit }
format.json { render json: #car.errors, status: :unprocessable_entity }
end
end
end
# DELETE /cars/1
# DELETE /cars/1.json
def destroy
#car.destroy
respond_to do |format|
format.html { redirect_to cars_url, notice: 'Car was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_car
#car = Car.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def car_params
params.fetch(:car, {})
end
end
I'd greatly appreciate any insight into this issue. I've followed every bit of advice I've seen on the internet regarding layouts, controllers, and views, and I'm having no luck.
Thanks in advance!

Thanks to everyone who was trying to answer my question! It was a stumper, but I've discovered the problem:
After uninstalling and reinstalling rails a few times, I created a dummy rails project and generated a new scaffold "car." Upon running rails server and loading up localhost:3000/cars, the default layout was rendered as normal. Thinking that reinstalling rails had solved it, I then linked the dummy project to a remote github repository.
At this point, running rails server and loading localhost:3000/cars showed me the same error message as before. This made me believe that something about the remote repo was messing up my project, so I googled around for this error message and github.
I stumbled upon the following link which ultimately answered my question:
https://github.com/rails/rails/issues/18660
Turns out, one of the directories in my root path was capitalized, and that was throwing rails off right away. As soon as I renamed the capitalized directory to all lowercase, the app ran flawlessly.
I'm frustrated by ruby on rails' extremely opinionated conventions, and especially since this project is almost a week late due to such an esoteric mistake. But I'm over the moon to have it running smoothly now and I hope this may help someone else in the future.
Thanks again all!

Related

Rails controller scaffold code

for a university project I'm looking to make some changes to the Rails scaffolding mechanism. Mainly, I want to know where controller scaffold code is generated.
When looking at where the code is generated I found what looked like the appropriate bits here: https://github.com/rails/rails/blob/master/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt
However, after changing it, it doesn't seem to make a difference. I tried both rails g scaffold .... and rails g scaffold_controller ....
I also noticed that the code that I end up with looks different from what I would expect from the template.
template:
# PATCH/PUT <%= route_url %>/1
def update
if #<%= orm_instance.update("#{singular_table_name}_params") %>
redirect_to <%= redirect_resource_name %>, notice: <%= "'#{human_name} was successfully updated.'" %>
else
render :edit
end
end
reality (dogs_controller.rb):
# PATCH/PUT /dogs/1
# PATCH/PUT /dogs/1.json
def update
respond_to do |format|
if #dog.update(dog_params)
format.html { redirect_to #dog, notice: 'Dog was successfully updated.' }
format.json { render :show, status: :ok, location: #dog }
else
format.html { render :edit }
format.json { render json: #dog.errors, status: :unprocessable_entity }
end
end
end
So mainly the generated code also responds to json requests, while the template does not look like it respects that.
The scaffolding console output also claims to invoke scaffold_controller.
Then there's also the code here: https://github.com/rails/rails/blob/master/railties/lib/rails/generators/rails/controller/templates/controller.rb.tt but that is even more bare bones.
Long story short, am I doing something wrong or where is the controller code for scaffolding generated.
FYI I cloned rails at commit a1f9fe8bdd4e6c4e20fbda424c0ecf2f31fabd30 and branched of from there, so fairly recently.

rails issue with naming convention and table

I have an issue with rails with naming convention.
I have a database where i can't rename table so names are not in plural with inflector.
Today i wanted create model and controller for the table "wishlist__c" and the issue is here. I tried 3 times first by duplicating product model, controller.... and changing name then creating files myself and i still got the issue and then with rails g scaffold wishlist__c
The first error when i try to go to url:8080/wishlist__c/index :
Routing Error
uninitialized constant WishlistCController
wishlist__c_controller.rb exist. I notice after many test that the double '__' is a problem in rails. I rename it to wishlist_c_controller and the same with the model. the error message change to
--Solution: I forget to rename folder wishlist__c to wishlist_c in views folder
Thanks you all ! --
ActiveRecord::RecordNotFound in WishlistCController#show
Couldn't find WishlistC with 'id'=index
the code display under this is from wishlist_c_controller.rb:
def set_wishlist__c
#wishlist__c = ::WishlistC.find(params[:id])
end
How to solve it. I need to link my app to this table
edit:
Model wishlist_c.rb:
class WishlistC < ApplicationRecord
self.table_name = "wishlist__c"
end
wishlist_c_controller:
class WishlistCController < ApplicationController
before_action :set_wishlist__c, only: [:show, :edit, :update, :destroy]
# GET /wishlist__c
# GET /wishlist__c.json
def index
#wishlist__c = WishlistC.all
end
# GET /wishlist__c/1
# GET /wishlist__c/1.json
def show
end
# GET /wishlist__c/new
def new
#wishlist__c = WishlistC.new
end
# GET /wishlist__c/1/edit
def edit
end
# POST /wishlist__c
# POST /wishlist__c.json
def create
#wishlist__c = WishlistC.new(wishlist__c_params)
respond_to do |format|
if #wishlist__c.save
format.html { redirect_to #wishlist__c, notice: 'Wishlist c was successfully created.' }
format.json { render :show, status: :created, location: #wishlist__c }
else
format.html { render :new }
format.json { render json: #wishlist__c.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /wishlist__c/1
# PATCH/PUT /wishlist__c/1.json
def update
respond_to do |format|
if #wishlist__c.update(wishlist__c_params)
format.html { redirect_to #wishlist__c, notice: 'Wishlist c was successfully updated.' }
format.json { render :show, status: :ok, location: #wishlist__c }
else
format.html { render :edit }
format.json { render json: #wishlist__c.errors, status: :unprocessable_entity }
end
end
end
# DELETE /wishlist__c/1
# DELETE /wishlist__c/1.json
def destroy
#wishlist__c.destroy
respond_to do |format|
format.html { redirect_to wishlist__c_index_url, notice: 'Wishlist c was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_wishlist__c
#wishlist__c = WishlistC.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def wishlist__c_params
params.fetch(:wishlist__c, {})
end
end
Rails create RESTful routes based on controller and model. One of the routes would be get wishlist__c/:id which gets mapped to action show of WishlistCController. so when you hit the URL wishlist__c/index it takes index as the id.
If you want to render index page, create a route get wishlist__c/index and map it to index method of your controller. For the above to work you must hit the URL url:8080/wishlist__c/1 where 1 is your WishList ID. Replace it with values of id column of wishlist__c table.
Looking at your controller, you already have a route get wishlist__c/ mapped to the index method of your controller. So url:8080/wishlist__c/ should render index page for your model.

How to create API in rails 5?

I am new to web service and Rails too. I have a doubt in creating API using rails 5. How do I create an API for a rails 5 application? I can find some tutorials for API only applications using rails 5. But I need both API and views in a single rails 5 application. How should I do that?
You can create a new rails project as usual:
$ rails new my_project
$ cd my_project
$ bundle
And then you can use scaffold to generate some code:
$ rails g scaffold Product name:string price:float
And migrate your database:
$ rails db:migrate # => update the database
You can now have a look at app/controllers/products_controller.rb
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
#products = Product.all
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
#product = Product.new
end
# GET /products/1/edit
def edit
end
# POST /products
# POST /products.json
def create
#product = Product.new(product_params)
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render :show, status: :created, location: #product }
else
format.html { render :new }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if #product.update(product_params)
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: #product }
else
format.html { render :edit }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
#product.destroy
respond_to do |format|
format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
#product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit(:name, :price)
end
end
As you can see there's respond_to in the create action. This is how you can respond to different request types.
Read more about it: http://edgeapi.rubyonrails.org/classes/ActionController/MimeResponds.html#method-i-respond_to
I've my own solution to build API very quickly https://github.com/igorkasyanchuk/fake_api at least on the stage of prototyping.
Using this gem I was able to provide a skeleton of the API for Frontend team, later it was changed to regular rails controllers.
While create a RESTful API, According to Rails 5 release notes, generating an API only application will:
Start the application with a limited set of middleware
Make the ApplicationController inherit from ActionController::API instead of ActionController::Base
Skip generation of view files,
I am listing down article/ Blog post's link read those:
Best Pratices for API only rails app
Rails Api only Web app
Rails Token based authentication: API only rails web app
Must read, Api only rails web app
Read this also, rails api only web app
Restful API with rails
Create a REST Api with Rails
Create a REST Api with Rails 5
Read any one of the above blog and just go through others for getting additional details or for the knowledge purpose
Have a Great Coding! 😀👨‍💻👩‍💻
Just build you regular rails app and when you need a API behavior on that method just respond with a json like this
def index
#cards = Card.all
render json: { status: 'Success', message: 'Loaded all cards', data: #cards }, status: :ok
end
If you really need the additional behavior from the controller to you can just take a regular controller and change the inheritance to something like this
class CardsController < ActionController::API
#your code
end
For more information on this specifically checkout Rails API Applications

CSRF Error in Production: ActionController::InvalidCrossOriginRequest

I am getting the following error on my comments controller in my production environments only (works fine in development). The user flow is as follows: I have jQuery that runs when a specific button is pushed which renders a partial file to add a new comment, a simple form. The respond_to method for the .js request in the controller is for new.js.erb file. This should be relatively easy to do but something is going wrong in the Rails (I am using Rails 4.1.1) code or on my server (Rackspace Cloud Server). The error is below:
ActionController::InvalidCrossOriginRequest in CommentsController#new
Security warning: an embedded tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript embedding.
I have tried the following code in my comments controller (does not work). It simply renders the .js file in the browser as a text string (javascript does not work).
protect_from_forgery except: :new
skip_before_action :verify_authenticity_token
I have tried removing the protect_from_forgery with: :exception method in the application_controller.rb file but it does not work (just renders the javascript in the browser as a text string).
I have tried replacing "protect_from_forgery with: :exception" with "protect_from_forgery with: :null_session" and this does not work either (gives the same InvalidCrossOriginRequest error above).
I am running out of options to fix this. Again, it's only happening in production. On my local machine (via localhost), everything works fine. The code for my comments controller is below:
class CommentsController < ApplicationController
# before_action :set_comment, only: [:show, :edit, :update, :destroy]
before_action :load_topic
before_action :authenticate_user!
# protect_from_forgery except: :new
# skip_before_action :verify_authenticity_token
# GET /comments
# GET /comments.json
def index
#comments = Comment.all
end
# GET /comments/1
# GET /comments/1.json
def show
end
# GET /comments/new
def new
#comment = Comment.new
end
# GET /comments/1/edit
def edit
end
# POST /comments
# POST /comments.json
def create
#comment = #topic.comments.new(comment_params)
#comment.user_id = current_user.id
respond_to do |format|
if #comment.save
format.html { redirect_to #topic, notice: 'Comment was successfully created.' }
format.json { render :show, status: :created, location: #comment }
format.js
else
format.html { redirect_to #article, alert: 'Unable to add comment' }
format.json { render json: #comment.errors, status: :unprocessable_entity }
format.js { render 'fail_create.js.erb'}
end
end
end
# PATCH/PUT /comments/1
# PATCH/PUT /comments/1.json
def update
respond_to do |format|
if #comment.update(comment_params)
format.html { redirect_to #comment, notice: 'Comment was successfully updated.' }
format.json { render :show, status: :ok, location: #comment }
else
format.html { render :edit }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /comments/1
# DELETE /comments/1.json
def destroy
#comment = #topic.comments.find(params[:id])
#comment.destroy
respond_to do |format|
format.html { redirect_to #topic, notice: 'Comment was successfully deleted.' }
format.json { head :no_content }
format.js
end
end
private
def load_topic
#topic = Topic.find(params[:topic_id])
end
# Use callbacks to share common setup or constraints between actions.
def set_comment
#comment = Comment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def comment_params
params.require(:comment).permit(:topic_id, :body, :name)
end
end
Any advice on fixing this issue would be appreciated.
Has this actually happened to real users or are you only seeing this error in your logs/monitoring?
This error tends to happen when crawlers are visiting your site (which obviously doesn't happen in your development environment).
The documentation is suggesting you add these to your controller action:
skip_before_action :verify_authenticity_token, if: :json_request?
protected
def json_request?
request.format.json?
end
However, if this is not the case, I think you actually have a CORS problem. 2 possible reasons:
Is your site available via HTTP and HTTPS? These are different origins!
Do you have multiple domains running this site? Try to inspect/log the request headers and see if there is any difference in the Origins.
You can try reproducing this in development too, if you edit your hosts file and point a domain to your local server.

My Rails controller test is not inheriting the ApplicationController methods

I have an ApplicationController with a given method in the public area
def current_user
session[:user]
end
and another controller
ObjetosController < ApplicationController
which needs to access such method, and I'm getting a horrible error while running my tests (rake test:functionals):
NameError: undefined local variable or method `current_user' for
I'm using Ruby 2.0.0 and Rails 4.0. I've been travelling Google and StackOverflow for hours and hours and haven't found anything about it.
Maybe someone can give me a hint or help me search for an answer please?
If it helps, if I put crap inside ApplicationController, and run the test, it doesn't complain!!! It's like it was loading another version of this class...
Here my ObjetosController code:
class ObjetosController < ApplicationController
before_action :set_objeto, only: [:show, :edit, :update, :destroy]
# GET /objetos
# GET /objetos.json
def index
#objetos = Objeto.all
end
# GET /objetos/1
# GET /objetos/1.json
def show
end
# GET /objetos/new
def new
#objeto = Objeto.new
end
# GET /objetos/1/edit
def edit
end
# POST /objetos
# POST /objetos.json
def create
#objeto = Objeto.new(objeto_params)
respond_to do |format|
if #objeto.save
format.html { redirect_to #objeto, notice: 'Objeto was successfully created.' }
format.json { render action: 'show', status: :created, location: #objeto }
else
format.html { render action: 'new' }
format.json { render json: #objeto.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /objetos/1
# PATCH/PUT /objetos/1.json
def update
current_user
respond_to do |format|
if #objeto.update(objeto_params)
format.html { redirect_to #objeto, notice: 'Objeto was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #objeto.errors, status: :unprocessable_entity }
end
end
end
# DELETE /objetos/1
# DELETE /objetos/1.json
def destroy
#objeto.destroy
respond_to do |format|
format.html { redirect_to objetos_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_objeto
#objeto = Objeto.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def objeto_params
params.require(:objeto).permit(:nombre, :codigo_sgej)
end
end
Solved it.
In my ApplicationController class I was instantiating some classes dynamically defined for each environment. I was also using some constants defined per environment.
As this app hasn't been released to staging or production yet, I had such values defined only in config/environments/development.rb file. I added them to config/environments/test.rb and now it works!
I lost hours with this problem, I'm really dissapointed with rails (or ruby?) for not showing any error at all...

Resources