Rails: Application.html.erb suddently stopped rendering - ruby-on-rails

I was doing something completely different with my app, when suddently my application.html.erb stopped rendering in my views. I even took back all the changes I had made and that did not fix the problem. What can have happened? I've searched everywhere and tried different things, nothing works. Everything else works fine. Here are the files with the changes.
application_controller
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
helper_method :current_user
def initialize(attributes = {})
#name = attributes[:name]
#email = attributes[:email]
end
def createRound
#gamerounds = Gameround.all
#gameround = Gameround.new({endtime: 'John Appleseed', active: true})
respond_to do |format|
if #gameround.save
format.html { redirect_to #gameround, notice: 'Gameround was successfully created.' }
format.json { render :show, status: :created, location: #gameround }
else
format.html { render :new }
format.json { render json: #gameround.errors, status: :unprocessable_entity }
end
end
end
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
def admin_user
#admin_user = User.find_by(username: 'Admin')
end
protected
def authenticate_user
if session[:user_id]
# set current user object to #current_user object variable
#current_user = User.find session[:user_id]
return true
else
redirect_to(:controller => 'sessions', :action => 'login')
return false
end
end
def save_login_state
if session[:user_id]
redirect_to(:controller => 'sessions', :action => 'profile')
return false
else
return true
end
end
end
game_session controller
class GamesessionsController < ApplicationController
before_action :set_gamesession, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user, :except => [:index, :show, :new ]
layout :application
# GET /gamesessions
# GET /gamesessions.json
def index
#gamesessions = Gamesession.all
end
# GET /gamesessions/1
# GET /gamesessions/1.json
def show
end
# GET /gamesessions/new
def new
#gamesession = Gamesession.new
unless !session[:user_id]
if !current_user.admin?
redirect_to '/play'
end
end
end
# GET /gamesessions/1/edit
def edit
end
# POST /gamesessions
# POST /gamesessions.json
def create
Gamesession.delete_all
#gamesession = Gamesession.new(gamesession_params)
createRound
end
# PATCH/PUT /gamesessions/1
# PATCH/PUT /gamesessions/1.json
def update
respond_to do |format|
if #gamesession.update(gamesession_params)
format.html { redirect_to #gamesession, notice: 'Gamesession was successfully updated.' }
format.json { render :show, status: :ok, location: #gamesession }
else
format.html { render :edit }
format.json { render json: #gamesession.errors, status: :unprocessable_entity }
end
end
end
# DELETE /gamesessions/1
# DELETE /gamesessions/1.json
def destroy
#gamesession.destroy
respond_to do |format|
format.html { redirect_to gamesessions_url, notice: 'Gamesession was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_gamesession
#gamesession = Gamesession.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def gamesession_params
params.require(:gamesession).permit(:players, :flares, :aliens, :gamesetup, expansion:[], level:[])
end
end
config.routes
Rails.application.routes.draw do
resources :gamerounds do
resources :currentplayers
end
resources :gamesessions
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# Artikkel, Alien liste
resources :expansions do
resources :aliens
end
resources :users
# You can have the root of your site routed with "root"
root 'gamesessions#new'
get "signup", :to => "users#new"
get "login", :to => "sessions#login"
post "login_attempt", :to => "sessions#login_attempt"
get "logout", :to => "sessions#logout"
get "profile", :to => "sessions#profile"
get "setting", :to => "sessions#setting"
get "play", :to => "gamesessions#index"
get "aliens", :to => "aliens#index"
#match ':controller(/:action(/:id))(.:format)'
# Example of regular route:
# get 'products/:id' => 'catalog#view'
# Example of named route that can be invoked with purchase_url(id: product.id)
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
# Example resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Example resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Example resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Example resource route with more complex sub-resources:
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', on: :collection
# end
# end
# Example resource route with concerns:
# concern :toggleable do
# post 'toggle'
# end
# resources :posts, concerns: :toggleable
# resources :photos, concerns: :toggleable
# Example resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
end

You are defining the initialize method in your controller without calling super.
def initialize(attributes = {})
#name = attributes[:name]
#email = attributes[:email]
super
end

Related

Rails Resources new and edit routes redirecting to root page instead of their respective routes

Basically, I'm trying to update the layout of my portfolio/new form but whenever I type in 'localhost:3000/portfolios/new' I get redirected to my home page. Same with 'localhost:3000/portfolios/(:id)/edit'
My routes are below:
Rails.application.routes.draw do
#Devise Routes
devise_for :users, path: '', path_names: { sign_in: 'login', sign_out: 'logout', sign_up: 'register' }
#homepages routes
get 'about-me', to: 'pages#about'
get 'contact', to: 'pages#contact'
# blog
resources :blogs do
member do
get :toggle_status
end
end
#portfolio
resources :portfolios, except: [:show]
get 'portfolio/:id', to: 'portfolios#show', as: 'portfolio_show'
get 'react-items', to: 'portfolios#react'
# setting root path --> ex: localhost:3000/
root to: 'pages#home'
end
Here is my controller:
class PortfoliosController < ApplicationController
before_action :set_portfolio_item, only: [:edit, :update, :show, :destroy]
layout "portfolio"
access all: [:show, :index, :react], user: {except: [:destroy, :new, :create, :update, :edit]}, site_admin: :all
def index
#portfolio_items = Portfolio.all
end
# custom scope
def react
#react_portfolio_items = Portfolio.react
end
def show
end
def new
# new portfolio item is initialized.
#portfolio_item = Portfolio.new
3.times { #portfolio_item.technologies.build }
end
def create
#portfolio_item = Portfolio.new(portfolio_params)
respond_to do |format|
if #portfolio_item.save
format.html { redirect_to portfolios_path, notice: 'Portfolio Item was successfully created.' }
else
format.html { render :new }
end
end
end
def edit
end
def update
respond_to do |format|
if #portfolio_item.update(portfolio_params)
format.html { redirect_to portfolios_path, notice: 'Portfolio Item was successfully updated.' }
else
format.html { render :edit}
end
end
end
def destroy
# destroy the record
#portfolio_item.destroy
# redirect
respond_to do |format|
format.html { redirect_to portfolios_url, notice: 'Record was removed.' }
end
end
private
def portfolio_params
params.require(:portfolio).permit(:title,
:subtitle,
:body,
technologies_attributes: [:name]
)
end
def set_portfolio_item
#portfolio_item = Portfolio.find(params[:id])
end
end
So overall I'm not sure why it's doing that. When I do rails routes I can see the correct paths but when I input them in the browser, they do not work.
Any help would be greatly appreciated.
I think you had reverted access to create/update/edit/destroy.
Remove except condition from access_all for user create/update/edit/destroy
when user trying to opening a page which doesn't has permission to view, it will be redirect_to its root_path by default.

Rails - same route for more than one of the same http methods

Is there any way that it's possible for me to have the same URL for multiple actions (in different controllers) where the HTTP method is the same?
e.g.
get 'users/:username/profile' => 'users#profile', as: :user_profile
put 'users/:username/profile' => 'users#avatar_upload', as: :edit_user_avatar
post 'users/:username/profile' => 'users#update', as: :user_edit_profile
post 'users/:username/profile' => 'userspayment#create', as: :add_user_payment_details
post 'users/:username/profile' => 'userspayment#update', as: :user_edit_payment_details
Currently I have:
get 'users/:username/profile' => 'users#profile', as: :user_profile
put 'users/:username/profile' => 'users#avatar_upload', as: :edit_user_avatar
post 'users/:username/profile' => 'users#update', as: :user_edit_profile
post 'users/:username/profile/payment-details/add' => 'userspayment#create', as: :add_user_payment_details
post 'users/:username/profile/payment-details/edit' => 'userspayment#update', as: :user_edit_payment_details
But when I run the add or update method in userspayment_controller.rb I'm rendering the users/profile view afterwards and the URL changes. I don't want to redirect because the add and update forms are in tabs and a redirect will make the first tab active. This is my UserpaymentsController:
class UserspaymentController < ApplicationController
before_action :authenticate_user!
before_action :set_user
def create
respond_to do |format|
#user_payment_details = UsersPaymentDetails.new(users_payment_details_params)
if #user_payment_details.save
record_activity('Updated payment information.')
format.html { render :template => "users/profile", :locals => { :user => #user }, notice: 'Payment details was successfully updated.' }
format.json { render :show, status: :ok, location: #user }
else
format.html { render(:file => Rails.root.join('public', '422'), :formats => [:html], :status => 422, :layout => false) }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
#user_payment_details = UsersPaymentDetails.find_by(user_id: #user.id)
if #user_payment_details.update(users_payment_details_params)
record_activity('Updated payment information.')
format.html { render :template => "users/profile", :locals => { :user => #user }, notice: 'Payment details was successfully updated.' }
format.json { render :show, status: :ok, location: #user }
else
format.html { render(:file => Rails.root.join('public', '422'), :formats => [:html], :status => 422, :layout => false) }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find_by(username: params[:username])
end
# Never trust parameters from the scary internet, only allow the white list through.
def users_payment_details_params
params.require(:users_payment_details).permit(:bank, :branch, :code, :account, :holder, :user_id)
end
end
As the other comment stated, your approach isn't going to work. However...
In your routes.rb, you could do:
resources :users, param: :user_name
scope :users do
patch ':user_name/*other', controller: :users, action: :update
get ':user_name/*other', controller: :users, action: :show
post ':user_name/*other', controller: :users, action: :create
end
Which will give you:
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:user_name/edit(.:format) users#edit
user GET /users/:user_name(.:format) users#show
PATCH /users/:user_name(.:format) users#update
PUT /users/:user_name(.:format) users#update
DELETE /users/:user_name(.:format) users#destroy
PATCH /users/:user_name/*other(.:format) users#update
GET /users/:user_name/*other(.:format) users#show
POST /users/:user_name/*other(.:format) users#create
Now, when you have a url like:
/users/foo-bar/profile
it will route to the appropriate update, show, or create action (depending on the HTTP verb) with a params[:other] equal to profile.
In your ApplicationController, you could do something like:
class ApplicationController < ActionController::Base
private
def call_action_service
action_service.call params.except(:controller, :action, :other)
end
def action_service
"#{params[:controller].camelize}::#{params[:other].gsub('-','_').camelize}::#{params[:action].camelize}Service".constantize
end
end
So, if you did a get on /users/foo-bar/profile, then action_service would resolve to:
Users::Profile::ShowService
And you could make your UsersController something like:
class UsersController < ApplicationController
def show
unless params[:other]
# do regular show
else
call_action_service
end
end
def update
unless params[:other]
# do regular update
else
call_action_service
end
end
def create
unless params[:other]
# do regular create
else
call_action_service
end
end
private
end
You'll note that you have only the RESTful actions, now (show, update, create, etc.) and have done away with non-RESTful actions (like profile, and avatar_upload).
So, in the end, the following HTTP verbs and urls will call the services:
GET /users/:user_name/profile == calls ==> Users::Profile::ShowService
PATCH /users/:user_name/profile == calls ==> Users::Profile::UpdateService
PATCH /users/:user_name/profile/avatar == calls ==> Users::Profile::Avatar::UpdateService
PATCH /users/:user_name/profile/payment-details == calls ==> Users::Profile::PaymentDetails::UpdateService
POST /users/:user_name/profile/payment-details == calls ==> Users::Profile::PaymentDetails::CreateService
If we continue with the example of making a get call to /users/foo-bar/profile, then you'll need a Users::Profile::ShowService:
#app/services/users/profile/show_service.rb
module Users
module Profile
class ShowService < ServiceBase
def call
# do useful stuff
end
end
end
end
You'll also need ServiceBase:
#app/services/service_base.rb
class ServiceBase
attr_accessor *%w(
args
).freeze
class << self
def call(args={})
new(args).call
end
end
def initialize(args)
#args = args
end
def call
# this is the fall back `call` method for all services
end
end
To make generating your paths easier, you might do something like:
#app/helpers/application_helper.rb
module ApplicationHelper
def other_user_path(other)
user_path(#user.name).send(:<<, "/#{other}")
end
end
So that you could do something like:
other_user_path('profile/payment-details')
and get
/users/foo-bar/profile/payment-details
Naturally, you'll want to add back in your respond_to do |format| stuff. But, I'll leave that to you to fiddle with.

Dry repeated methods and routes in Rails

I'm new to ruby/rails and I have this situation with 3 resources which uses comments provided by the acts_as_votable gem. The thing is, I have added the necessary methods and routes in all of the resources, resulting in a complete non-dry aberration.
My routes are:
Rails.application.routes.draw do
root to: 'home#index'
get 'home/index', to: 'home#index'
resources :users
get 'thinga/tagged/:tag', to: 'thinga#tags', as: 'tagged_thingas'
get 'thingb/tagged/:tag', to: 'thingb#tags', as: 'tagged_thingbs'
resources :thinga do
member do
get :like
get :dislike
get :unvote
end
end
resources :thingb do
member do
get :like
get :dislike
get :unvote
end
end
resources :thingc, only: [:create, :update, :destroy] do
member do
get :like
get :dislike
get :unvote
end
end
devise_for :users, path: 'auth',
:controllers => { :omniauth_callbacks => 'omniauth_callbacks' }
end
In the controllers the repeated code is
def like
#thinga = Thinga.find(params[:id])
#thinga.liked_by current_user
respond_to do |format|
format.html { redirect_to :back }
format.js { render layout: false }
end
end
def dislike
#thinga = Thinga.find(params[:id])
#thinga.disliked_by current_user
respond_to do |format|
format.html { redirect_to :back }
format.js { render layout: false }
end
end
def unvote
#thinga = Thinga.find(params[:id])
#thinga.unvote_by current_user
respond_to do |format|
format.html { redirect_to :back }
format.js { render layout: false }
end
end
Can someone help me to learn how to dry off this cases please?. Thank you.
Try rails routes concerns
http://edgeguides.rubyonrails.org/routing.html#routing-concerns
And I think you'll be able to do this
concern :votable do
member do
get :like
get :dislike
get :unvote
end
end
resources :thinga, :thingb, :concerns => :votable
resources :thingc, :concerns => :votable, only: [:create, :update, :destroy]
For the controllers - Make a VotablesController and have the ThingasController or ThingbsController subclass it. You can call a before action to set the #votable instance variable and have the subclasses set the variable. The shared methods will be in one place.
class VotablesController < ApplicationController
before_action :set_votable
def like
#votable.liked_by current_user
respond_to do |format|
format.html { redirect_to :back }
format.js { render layout: false }
end
end
def dislike
#votable.disliked_by current_user
respond_to do |format|
format.html { redirect_to :back }
format.js { render layout: false }
end
end
def unvote
#votable.unvote_by current_user
respond_to do |format|
format.html { redirect_to :back }
format.js { render layout: false }
end
end
end
in the subclasses (this is an example for thinga)
class ThingasController < VotablesController
def set_votable
#votable = Thinga.find(params[:id])
end
end
Ruby provides a lot of scope for using code to write code (metaprogramming), so you should be able to write a method that will do the job of adding the repeated routes for you. Perhaps the following code will run:
Rails.application.routes.draw do
def create_votes_resources(name, options = {})
resources name, options do
member do
get :like
get :dislike
get :unvote
end
end
end
create_votes_resources :thing_a
create_votes_resources :thing_b
create_votes_resources :thing_c, only: [:create, :update, :destroy]
end

RAILS : uninitialized constant PhotosController::Photo [Ruby on rails]

He, I have a problem with my code and I'm looking for a solution for 2 hours now. I'm new on ruby on rails ( and rails .. ) and I have this error :
NameError in PhotosController#new
uninitialized constant PhotosController::Photo
here my code so you can help me on it !
photos_controller.rb :
class PhotosController < ApplicationController
before_action :set_photo, only: [:show, :edit, :update, :destroy]
# GET /photos
# GET /photos.json
def index
#photos = Photo.all
end
# GET /photos/1
# GET /photos/1.json
def show
end
# GET /photos/new
def new
#photo = Photo.new
end
# GET /photos/1/edit
def edit
end
# POST /photos
# POST /photos.json
def create
#photo = Photo.new(photo_params)
respond_to do |format|
if #photo.save
format.html { redirect_to #photo, notice: 'Photo was successfully created.' }
format.json { render action: 'show', status: :created, location: #photo }
else
format.html { render action: 'new' }
format.json { render json: #photo.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /photos/1
# PATCH/PUT /photos/1.json
def update
respond_to do |format|
if #photo.update(photo_params)
format.html { redirect_to #photo, notice: 'Photo was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #photo.errors, status: :unprocessable_entity }
end
end
end
# DELETE /photos/1
# DELETE /photos/1.json
def destroy
#photo.destroy
respond_to do |format|
format.html { redirect_to photos_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_photo
#photo = Photo.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def photo_params
params.require(:photo).permit(:image)
end
end
photo.rb :
class Photo < ActiveRecord::Base
has_attached_file :image
end
The page I temp to reach ( //.../photos/new ) :
new.html.erb :
<h1>New photo</h1>
and my route file :
PYL::Application.routes.draw do
get "photos/test"
get "photos/update"
get "photos/show"
get "photos/new"
resources :photos
get "photos/new"
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
root 'photo#index'
# Example of regular route:
# get 'products/:id' => 'catalog#view'
# Example of named route that can be invoked with purchase_url(id: product.id)
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
# Example resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Example resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Example resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Example resource route with more complex sub-resources:
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', on: :collection
# end
# end
# Example resource route with concerns:
# concern :toggleable do
# post 'toggle'
# end
# resources :posts, concerns: :toggleable
# resources :photos, concerns: :toggleable
# Example resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
end
If you have an idea, please help me :)
You named your model class Photos instead of Photo. It should be:
class Photo < ActiveRecord::Base
has_attached_file :image
end

How do I add an additional resource action to my routes?

I have a resource named Volunteers:
class VolunteersController < ApplicationController
before_filter :authenticate_user!
def index
##volunteers = Volunteer.all()
#volunteers = Volunteer.paginate(:page => params[:page])
end
def show
#volunteer = Volunteer.find(params[:id])
end
def new
#volunteer = Volunteer.new
end
def create
#post = Volunteer.new(volunteer_params)
#post.save
redirect_to #post
end
def destroy
#volunteer = Volunteer.find(params[:id])
#volunteer.destroy
redirect_to :action => 'index'
end
def search
#volunteers = Volunteer.search params[:search]
end
private
def volunteer_params
params.require(:volunteer).permit(:forename, :surname)
end
end
I have added an additional action called search but I'm having issues mapping it in my routes file:
root 'home#index'
resources :volunteers
How do I map to the search action (including params)?
There is an example in the route file itself:
# Example resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
You need to add the search method as a post (or whatever is appropriate) option for the resource, you can either add it to collection or member - collection methods won't look for a specific item id in the url, which is appropriate for a search method.
resources :volunteers do
collection do
post :search
end
end

Resources