I am coding a Ruby on Rails app (rails 4), on an ubuntu machine.
I have created a new scaffold (model/view/controller) via rails g scaffold common_warnings , and it works just fine on my local machine (localhost:3000/common_warnings resolves to something appropriate), however when I upload this to my server, I get this error:
ActionController::RoutingError (uninitialized constant CommonWarningsController)
when trying to get mydomain.com/common_warnings.
I know that sometimes pluralization is a problem, these are the first lines of each of my controller and model files:
app/controllers/common_warnings_controller.rb
class CommonWarningsController < ApplicationController
app/models/common_warning.rb
class CommonWarning < ActiveRecord::Base
My rails app already has 30something tables in the database, I know I did have this problem a while ago but just can't work out how to fix this one. The pluralization seems to match what I do for loan_histories_controller.rb (also a multi-word name).
The output of rake routes is the same on my local machine and on the server. This is the relevant output:
rake routes | grep common
common_warnings GET /common_warnings(.:format) common_warnings#index
POST /common_warnings(.:format) common_warnings#create
new_common_warning GET /common_warnings/new(.:format) common_warnings#new
edit_common_warning GET /common_warnings/:id/edit(.:format) common_warnings#edit
common_warning GET /common_warnings/:id(.:format) common_warnings#show
PATCH /common_warnings/:id(.:format) common_warnings#update
PUT /common_warnings/:id(.:format) common_warnings#update
DELETE /common_warnings/:id(.:format) common_warnings#destroy
"The server" in this case is provided by AWS
This is my complete common warnings controller:
class CommonWarningsController < ApplicationController
before_action :set_common_warning, only: [:show, :edit, :update, :destroy]
before_action :signed_in_user
before_action :admin_user
# GET /common_warnings
# GET /common_warnings.json
def index
#common_warnings = CommonWarning.all
end
# GET /common_warnings/1
# GET /common_warnings/1.json
def show
end
# GET /common_warnings/new
def new
#new_or_edit = 'new'
#common_warning = CommonWarning.new
end
# GET /common_warnings/1/edit
def edit
#new_or_edit = 'edit'
end
# POST /common_warnings
# POST /common_warnings.json
def create
#common_warning = CommonWarning.new(common_warning_params)
respond_to do |format|
if #common_warning.save
format.html { redirect_to #common_warning, notice: 'Common warning was successfully created.' }
else
format.html { render action: 'new' }
end
end
end
# PATCH/PUT /common_warnings/1
# PATCH/PUT /common_warnings/1.json
def update
respond_to do |format|
if #common_warning.update(common_warning_params)
format.html { redirect_to #common_warning, notice: 'Common warning was successfully updated.' }
else
format.html { render action: 'edit' }
end
end
end
# DELETE /common_warnings/1
# DELETE /common_warnings/1.json
def destroy
#common_warning.destroy
respond_to do |format|
format.html { redirect_to common_warnings_url }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_common_warning
#common_warning = CommonWarning.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def common_warning_params
params.require(:common_warning).permit(:name)
end
def signed_in_user
store_location
redirect_to signin_url, notice: "Please sign in." unless signed_in?
end
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end
Thanks in advance!
Fixed. It was a complicated problem to do with having multiple similar but not identical rails apps running from one server. I had forgotten to reset the connection to the schema migrations. Thanks to those who responded!
Related
I'm trying to build a blog using rails in c9 ubuntu setup. While I was optimizing routes, I realized that my url in browser does not change along with my actions, though everything works just fine.
The url that can be seen in the browser is actually set to display all the blogs' posts, and it does, but when I try to click on only one (in this case 'My Blog Post 1') it performs the action, but url remains the same.
However, if I type the correct url manually, it also works.
Everything is working, but my url doesn't change automatically, but I have to do it manually. In this stage I can handle that, but I'm afraid I'll have problems with that later on. This is my first time that I use cloud9 environment.
Controller:
class BlogsController < ApplicationController
before_action :set_blog, only: [:show, :edit, :update, :destroy]
# GET /blogs
# GET /blogs.json
def index
#blogs = Blog.all
end
# GET /blogs/1
# GET /blogs/1.json
def show
end
# GET /blogs/new
def new
#blog = Blog.new
end
# GET /blogs/1/edit
def edit
end
# POST /blogs
# POST /blogs.json
def create
#blog = Blog.new(blog_params)
respond_to do |format|
if #blog.save
format.html { redirect_to #blog, notice: 'Blog was successfully created.' }
else
format.html { render :new }
end
end
end
# PATCH/PUT /blogs/1
# PATCH/PUT /blogs/1.json
def update
respond_to do |format|
if #blog.update(blog_params)
format.html { redirect_to #blog, notice: 'Blog was successfully updated.' }
else
format.html { render :edit }
end
end
end
# DELETE /blogs/1
# DELETE /blogs/1.json
def destroy
#blog.destroy
respond_to do |format|
format.html { redirect_to blogs_url, notice: 'Blog was successfully destroyed.' }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_blog
#blog = Blog.friendly.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def blog_params
params.require(:blog).permit(:title, :body)
end
end
Routes:
Rails.application.routes.draw do
resources :portofolioos, except: [:show]
get 'portofolioo/:id', to: 'portofolioos#show', as: 'portofolioo_show'
get 'about', to: 'pages#about'
get 'contact', to: 'pages#contact'
resources :blogs
root to: 'pages#home'
end
View just has a form. It's pretty much scaffold, I only changed show page to display id in url and added friendly_id gem, but none of it is displayed in url, but it works just fine.
<p><%= link_to portofolio_item.title, portofolioo_show_path(portofolio_item) %></p>
I get the following error, Couldn't find User with 'id'=
I have this in my Users_Controller,
def edit
#user = #signed_in_user
end
This is in my routes.rb,
root 'welcome#welcome'
get 'login' => 'sessions#login', :as => :login
get 'profile' => 'users#profile', :as => :profile
post 'logging/user' => 'sessions#create'
get 'logout' => 'sessions#destroy', :as => :logout
get 'about' => 'about'
resources :users
get 'register' => 'users#new', :as => :register
get 'edit' => 'users#edit', :as => :edit
This is in my application_controller.rb,
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :set_user
protected
def set_user
unless session[:user_id] == nil
#signed_in_user = User.find(session[:user_id])
end
end
end
This is in my Users_Controller
Here is my code from my User_Controller on creating the account
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
# GET /users
# GET /users.json
def index
#users = User.all
end
def profile
#user = User.find(session[:user_id]) unless session[:user_id] == ""
redirect_to login_path, notice: "You're not logged in" unless #user
end
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
#user = #signed_in_user
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(:name, :password, :password_confirmation, :email, :age)
end
end
And this is the link that I use for my HTML,
<li role="presentation"><%= link_to 'Edit', edit_path %></li>
So, to start, a good practice when you get an 'Couldn't find' message is to check what instance variables are in your view.
So in a view, just type: <%= #user_id %> and see if anything shows up on your page, thus indicating if any user is even present! The other problem is that your instance variable might be <%= user.id %> but I am not sure as I can't see your code and how the user is stored in the database.
Second if you run rake routes, you generally find that the edit path will have a URI pattern like: "/edit(.:format)", meaning the route need "edit_path(#user.id)" rather than just "edit_path".
Let me know if this leads you anywhere or you have further questions and I hope I can answer them!
===========
Additional info:
Well without more code to look at, I would provide a few more suggestions...The goal is to have the <%= #user.id %> (or user_id) show up on the page somehow, thus telling you it is available.
The set_user method is an instance method, not a class method. To make it a class method, try def self.set_user. This invokes the method of the instance on the controller, thus making it a class method.
Make sure you have a session object to use. In the routes, it looks like post logging/user might be creating the session, but I am not sure.
Keep the edit_path(#user.id) or however the id is stored for the user as the route rather than just edit_path. I am pretty sure if you run 'rake routes', it will tell you that an additional variable needs to be passed for the link to work
Use the gem byebug Here is the link: https://github.com/deivid-rodriguez/byebug. You get this error while the edit page or where ever you are getting the error write in the action byebug. As you have mentioned in the console it shows a arrow pointing at a specific line in the application, the last line should appear as this (byebug), here write the variable in which you are getting the user id. If we take an example of your application controller in the set_user method:
def set_user
byebug
unless session[:user_id] == nil
#signed_in_user = User.find(session[:user_id])
end
end
In the console after (byebug) write session[:user_id] so this will give you the value of the session[:user_id]. So if this is null then you have a problem here or just follow the same procedure to check anywhere else.
Also there is one more thing you can do to learn is just create a new project or use the existing one and generate a scaffold which will give you options of show, edit, index. It will generate all the views, controller code, migration and everything. You can do that like this:
rails generate scaffold User email:string password:string
You can add more fields if you want. And then in your application just visit http://localhost:[port_no]/users which will by default take you to index page where you can add new users, edit existing ones. This will teach you about everything. It would be like a reference code for you. Read more at: http://guides.rubyonrails.org/command_line.html#rails-generate
And being more specific to users only there is a gem named Devise which will give you all the required things like sign_in, sign_up, session_management for users. Hope these things help you with your issue.
Edit:
Here is a very good tutorial link which will help you: https://www.railstutorial.org/book/updating_and_deleting_users#sec-updating_users
My app on Heroku shows this error:
We're sorry, but something went wrong.
If you are the application owner check the logs for more information.
So I ran Heroku logs and guessed this could be the problem:
ActiveRecord::UnknownAttributeError (unknown attribute: user_id):
app/controllers/pins_controller.rb:14:in `new'
My Pins controller
class PinsController < ApplicationController
before_action :set_pin, only: [:show, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
#pins = Pin.all
end
def show
end
def new
#pin = current_user.pins.build
end
def edit
end
def create
#pin = current_user.pins.build(pin_params)
if #pin.save
redirect_to #pin, notice: 'Pin was successfully created.'
else
render action: 'new'
end
end
def update
if #pin.update(pin_params)
redirect_to #pin, notice: 'Pin was successfully updated.'
else
render action: 'edit'
end
end
def destroy
#pin.destroy
redirect_to pins_url
end
private
# Use callbacks to share common setup or constraints between actions.
def set_pin
#pin = Pin.find(params[:id])
end
def correct_user
#pin = current_user.pins.find_by(id: params[:id])
redirect_to pins_path, notice: "Not authorized to edit this pin" if #pin.nil?
end
# Never trust parameters from the scary internet, only allow the white list through.
def pin_params
params.require(:pin).permit(:description, :image)
end
end
Anything wrong? Am I looking at the right place to debug?
Turns out I didn't do heroku run rake db:migrate. Thanks guys for that. Another error came up.
ArgumentError (missing required :bucket option):
app/controllers/pins_controller.rb:22:in `create'
Is this tied to Amazon Web Services?
You combined 2 issues into one question. For the first problem with the unknown attribute user_id you need to run:
heroku run rake db:migrate.
For the second problem with your ArgumentError (missing required :bucket option): error you need to set the heroku config to:
heroku config:set S3_BUCKET_NAME=nameOfYourBucket
I'd go in New action for plain
#pin = Pin.new
You are using your Create action to add the values from relations, so it should work fine
Other then that, use .new in New and .build in Create
UPDATED POST
I have an "uploads_controller.rb" file with custome method "refresh_table"
class UploadsController < ApplicationController
before_action :set_upload, only: [:show, :edit, :update, :destroy]
# GET /uploads
def index
#uploads = Upload.all
update_file_status
#uploads = Upload.all
end
# GET /uploads/1
def show
end
# GET /uploads/new
def new
puts "Running uploads/new"
#upload = Upload.new()
end
# GET /uploads/1/edit
def edit
end
# POST /uploads
def create
#upload = Upload.new(upload_params)
if #upload.save
#upload.update!(:status => "1")
#upload.update!(:f_path => "#{#upload.sourcedata.path}")
redirect_to uploads_url, notice: "Upload for #{#upload.task.name} was successfully created with file #{#upload.sourcedata_file_name}."
else
redirect_to tasks_url, alert: "*** ERROR *** Upload for #{#upload.task.name} did not go through successfully. #{#upload.errors.messages}"
end
end
# PATCH/PUT /uploads/1
def update
puts "Update method in Uploads controller received params = #{params.inspect}"
puts "params[:upload][:job] = #{params[:upload][:job].inspect}"
if (params[:upload][:job] == "parse")
puts "Passed params[:job]== \"parse\" "
redirect_to uploads_url, notice: "Parsing data from #{#upload.sourcedata_file_name}....."
#upload.delay.add_data_to_DB()
else
if #upload.update(upload_params)
redirect_to uploads_url, notice: "#{#upload.sourcedata_file_name} was updated"
else
redirect_to uploads_url, notice: "ERRRO #{#upload.sourcedata_file_name} could NOT be updated"
end
end
end
# DELETE /uploads/1
def destroy
#upload.destroy
redirect_to uploads_url, notice: 'Couldnt parse file #{#upload.sourcedata_file_name}'
end
# GET /uploads/refresh_table
def refresh_table
#uploads = Upload.all
update_file_status
#uploads = Upload.all
respond_to do |format|
format.html {redirect to 'index'}
format.js # template marked refresh_table.js.erb will be evoked
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_upload
#upload = Upload.find(params[:upload][:id])
end
# Only allow a trusted parameter "white list" through.
def upload_params
params.require(:upload).permit(:sourcedata, :task_id, :status, :f_path, :job)
end
def update_file_status
#uploads.each do |u|
if(File.exist?(u.f_path))
puts "File #{u.sourcedata_file_name} exists"
else
puts "File #{u.sourcedata_file_name} has been removed"
u.update!(:status => "-1")
end
end
end
end
routes.rb:
blah
blah
blah
resource :uploads do
member do
post "parse"
end
collection do
get "refresh_table", to: "refresh_table"
end
end
rake routes:
blah
blah
parse_uploads POST /uploads/parse(.:format) uploads#parse
refresh_table_uploads GET /uploads/refresh_table(.:format) refresh_table#refresh_table
uploads POST /uploads(.:format) uploads#create
new_uploads GET /uploads/new(.:format) uploads#new
edit_uploads GET /uploads/edit(.:format) uploads#edit
GET /uploads(.:format) uploads#show
PATCH /uploads(.:format) uploads#update
PUT /uploads(.:format) uploads#update
DELETE /uploads(.:format) uploads#destroy
Then I restarted the server and tried to test that the route works by typing this as the url
http://localhost:3000/uploads/refresh_table
This gave me an error in the browser:
ActionController::RoutingError at /uploads/refresh_table
uninitialized constant RefreshTableController
Local Variables
params
{:action=>"refresh_table", :controller=>"refresh_table"}
default_controller
true
controller_param
"refresh_table"
#<NameError: uninitialized constant RefreshTableController>
Server logs says:
Started GET "/uploads/refresh_table" for 127.0.0.1 at 2014-01-02 20:28:43 -0500
ActiveRecord::SchemaMigration Load (0.5ms) SELECT `schema_migrations`.* FROM `schema_migrations`
ActionController::RoutingError - uninitialized constant RefreshTableController:
Also noticed that the "index" method is gone from the routes.rb for uploads.
How can I fix this? Thanks
itsnikolay response is ok but generate this url : '
http://localhost:3000/upload/refresh_table ( with upload instead of uploads )
if you want to use http://localhost:3000/uploads/refresh_table you can add this line in your routes file :
match 'uploads/refresh_table', to: 'upload#refresh_table', via: :get
Hope this help.
resource :uploads do
member do
post "parse"
end
collection do
get "refresh_table"
end
end
Your respond_to block is the culprit.
Try:
respond_to do |format|
format.html { redirect_to uploads_path }
format.js # template marked refresh_table.js.erb will be evoked
end
redirect is not what you're looking for, you want redirect_to
I have a really strange error, when i submit my form to create a new admin i get this error:
NoMethodError in AdminsController#create
undefined method `admin?' for #<Admin:0x6c7f098>
in line:
if #admin.save
How is this error produced? I mainly used scaffold code and i only deletet the views of the controller! Here is my controller: I thank everybody for help!
class AdminsController < ApplicationController
before_action :set_admin, only: [ :edit, :update, :destroy]
# GET /admins/new
def new
#admin = Admin.new
end
# GET /admins/1/edit
def edit
end
# POST /admins
# POST /admins.json
def create
#admin = Admin.new(admin_params)
respond_to do |format|
if #admin.save
format.html { redirect_to adminpage_index_path, notice: 'Admin was successfully created.' }
else
redirect_to adminpage_index_path
end
end
end
# PATCH/PUT /admins/1
# PATCH/PUT /admins/1.json
def update
respond_to do |format|
if #admin.update(admin_params)
format.html { redirect_to adminpage_index_path , notice: 'Admin was successfully updated.' }
format.json { head :no_content }
else
redirect_to adminpage_index_path
end
end
end
# DELETE /admins/1
# DELETE /admins/1.json
def destroy
#admin.destroy
respond_to do |format|
format.html { redirect_to adminpage_index_path }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_admin
#admin = Admin.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def admin_params
params.require(:admin).permit(:username, :vorname, :nachname, :strasse, :ort, :plz, :telefon, :handy, :email, :password, :password_confirmation)
end
end
From what I can see, your Admin model probably does not inherit from ActiveRecord::Base. Make sure it does. The model should look like this:
class Admin < ActiveRecord::Base
# ...
end
Your admin model has a callback of some kind. i.e. before_save, after_save, after_validations. Something like that that is trying to call admin?
Post admin.rb file and the stack trace of the error and this should be easy to find.