I used "rails generate scaffold project" to create an new web application. I already did this in the past on Linux and Mac OSX running other versions of rails and ruby and all worked fine, but this time I'm working on Windows 7. Here is my environment
C:\Users\user1\Company>ruby -v
ruby 2.0.0p451 (2014-02-24) [x64-mingw32]
C:\Users\user1\Company>rails -v
DL is deprecated, please use Fiddle
Rails 4.1.0
C:\Users\user1\Company>
after I ran the scaffold command, I ran rake db:migrate and I was able to create my first project successfully. Then I can edit the project, but when I click update, I get the following error message
ArgumentError (When assigning attributes, you must pass a hash as an argument.):
Full server log message
Started PATCH "/projects/1" for 127.0.0.1 at 2014-04-29 05:16:33 -0700
Processing by projectsController#update as HTML
Parameters: {"utf8"=>"√", "authenticity_token"=>"gST6BUQNwOZQDYVj60DXLuFANv1JsM02YAIM+xYwt/M=", "commit"=>"Update project", "id"=>"1"}
project Load (0.0ms) SELECT "projects".* FROM "projects" WHERE "projects"."id"= ? LIMIT 1 [["id", 1]]
(1.0ms) begin transaction
(0.0ms) rollback transaction
Completed 500 Internal Server Error in 10ms
ArgumentError (When assigning attributes, you must pass a hash as an argument.):
app/controllers/projects_controller.rb:44:in `block in update'
app/controllers/projects_controller.rb:43:in `update'
Rendered C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/actionpack-4.1.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (2.0ms)
Rendered C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/actionpack-4.1.0/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.0ms)
Rendered C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/actionpack-4.1.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (2.0ms)
Rendered C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/actionpack-4.1.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (104.0ms)
Here is my "update" method (as was created automatically by the scaffold command)
# PATCH/PUT /projects/1
# PATCH/PUT /projects/1.json
def update
respond_to do |format|
if #project.update(project_params)
format.html { redirect_to #project, notice: 'Update Successful!' }
format.json { render :show, status: :ok, location: #project }
else
format.html { render :edit }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
I tried removing the "PATCH/" keyword, but no luck. I replaced the whole method with the following (this worked for my other application, but not this time on Windows)
# PATCH/PUT /projects/1
# PATCH/PUT /projects/1.json
def update
#project = Project.find(params[:id])
if #project.update_attributes(params[:project])
flash[:notice] = "Update Successful!"
end
respond_with(#project)
end
but this did not make any difference.
I also tried (I found this by browsing SO)
# PUT /projects/1
# PUT /projects/1.json
def update
#project = Project.find(params[:id])
respond_to do |format|
if #project.update_attributes(params[:project])
format.html { redirect_to #project, notice: 'Update Successful!' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
but no success either
Here are the other working methods (all as automatically generated by "rails generate scaffold" command, and they all work fine)
# GET /projects
# GET /projects.json
def index
#projects = project.all
end
# GET /projects/1
# GET /projects/1.json
def show
end
# GET /projects/new
def new
#project = project.new
end
# GET /projects/1/edit
def edit
end
# POST /projects
# POST /projects.json
def create
#project = project.new(project_params)
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: 'Creation Successful!' }
format.json { render :show, status: :created, location: #project }
else
format.html { render :new }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
Why is "rails generate scaffold" command not working on Windows and working fine on Linux and Mac OSX?
Update 1
Here are the other methods that were automatically created by "rails generate scaffold" command
class ProjectsController < ApplicationController
before_action :set_project, only: [:show, :edit, :update, :destroy]
<other methods listed above : index, show, new, edit, create, update, and destroy>
private
# Use callbacks to share common setup or constraints between actions.
def set_project
#project = Project.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def project_params
params[:project]
end
end
Working Code after making the changes suggested by Kirti Thorat
This is what worked for me
# PATCH/PUT /projects/1
# PATCH/PUT /projects/1.json
def update
#project = Project.find(params[:id])
respond_to do |format|
if #project.update(project_params)
format.html { redirect_to #project, notice: 'Project was successfully updated.' }
format.json { render :show, status: :ok, location: #project }
else
format.html { render :edit }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_project
#project = Project.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def project_params
params.require(:project).permit(:UnitMgtAddress)
end
You just created a scaffold without any other fields. So your projects table simply has 3 default fields id, created_at and updated_at. Because of which in your update action when you do:
if #project.update(project_params)
Or
if #project.update_attributes(params[:project])
you get error as update and update_attributes require a Hash as an argument and params[:project] is nil. Look at your params hash from server log
{"utf8"=>"√", "authenticity_token"=>"gST6BUQNwOZQDYVj60DXLuFANv1JsM02YAIM+xYwt/M=", "commit"=>"Update project", "id"=>"1"}
It doesn't have a key project.
Possible Solutions
Without adding new fields
If you are not planning to add any new fields in your projects table then there is no point in having an update action as what field would you update on?
With adding new fields
You can add new fields to your projects table like name, duration, etc as per your requirement (By creating a migration to add new fields).
After this you would just need to update the project_params method as below:
def project_params
params.require(:project).permit(:name, :duration)
end
Related
I have been recently trying to learn ruby by using ruby on rails with baserails. Everything was fine until I got in the spot in the tutorial where there wasn't much guidance on how to install s3 using paperclip the tutorial was for dropbox. I am so lost and have been getting errors for 2 days. I have researched this issue alot, but with my limited knowledge I am having a hard time understanding it. I know my issue is a paperclip/s3 issue. I have all my gems up to to date. Could someone please work with me and help guide me in fixing my issue. Here is my listings_controller.fb file. Line 66 gives me this error.
uninitialized constant ListingsController::Listing.
class ListingsController < ApplicationController
before_action :set_listing, only: [:show, :edit, :update, :destroy]
# GET /listings
# GET /listings.json
def index
#listings = Listing.all
end
# GET /listings/1
# GET /listings/1.json
def show
end
# GET /listings/new
def new
#listing = Listing.new
end
# GET /listings/1/edit
def edit
end
# POST /listings
# POST /listings.json
def create
#listing = Listing.new(listing_params)
respond_to do |format|
if #listing.save
format.html { redirect_to #listing, notice: 'Listing was successfully created.' }
format.json { render :show, status: :created, location: #listing }
else
format.html { render :new }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /listings/1
# PATCH/PUT /listings/1.json
def update
respond_to do |format|
if #listing.update(listing_params)
format.html { redirect_to #listing, notice: 'Listing was successfully updated.' }
format.json { render :show, status: :ok, location: #listing }
else
format.html { render :edit }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
# DELETE /listings/1
# DELETE /listings/1.json
def destroy
#listing.destroy
respond_to do |format|
format.html { redirect_to listings_url, notice: 'Listing was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_listing
#listing = Listing.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def listing_params
params.require(:listing).permit(:name, :description, :price, :image)
end
end
______________Terminal_______________-
Started GET "/listings/1" for 127.0.0.1 at 2017-02-09 21:36:39 +0900
Processing by ListingsController#show as HTML
Parameters: {"id"=>"1"}
Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms)
NameError (uninitialized constant ListingsController::Listing):
app/controllers/listings_controller.rb:67:in `set_listing' Rendering
/Users/chrisdionne/.rvm/gems/ruby-2.3.3/gems/actionpack-5.0.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
within rescues/layout Rendering
/Users/chrisdionne/.rvm/gems/ruby-2.3.3/gems/actionpack-5.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
Rendered
/Users/chrisdionne/.rvm/gems/ruby-2.3.3/gems/actionpack-5.0.1/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
(5.2ms) Rendering
/Users/chrisdionne/.rvm/gems/ruby-2.3.3/gems/actionpack-5.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb Rendered
/Users/chrisdionne/.rvm/gems/ruby-2.3.3/gems/actionpack-5.0.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.3ms) Rendering
/Users/chrisdionne/.rvm/gems/ruby-2.3.3/gems/actionpack-5.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
Rendered
/Users/chrisdionne/.rvm/gems/ruby-2.3.3/gems/actionpack-5.0.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
(1.3ms) Rendered
/Users/chrisdionne/.rvm/gems/ruby-2.3.3/gems/actionpack-5.0.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
within rescues/layout (161.7ms)
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.
I developed a simple toy app which models a user and a micro-post using scaffolds. This is my user_controller
source "railstutorial.org"
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
# GET /users
# GET /users.json
def index
#users = User.all
end
Method Show
# 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
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
Method update
# 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, :email)
end
end
Show method is used for rendering the user page with URL of the type "users/1".
However update method is to update our user's database, but after the update action is called it redirects us to the "users/1" URL.
In first case http request made is of type "GET" which routes us to "show" function/action, however in second case http request is of type "PATCH" which routes control to "update" function and this update function simply update the database, then why and how does it redirects us to "users/1". Does it call any rendering code somewhere ?
I am a beginner so please excuse me if question is a bit silly, but it would be a great help if someone could answer.
See at your code in update action after if #user.update(user_params)
You are calling redirect_to, it simply redirect you to new route which you provide it.
in this case its redirecting to show action as you are passing the object, you can provide any other route also.
read about redirect_to http://api.rubyonrails.org/classes/ActionController/Redirecting.html
#user is simply a user entry object who got an id in User Model, if you said redirect_to #user, it automatically detects the id of the user found in #user and redirects to /user/:id, rails is brave enough to understand that
I am trying to update a post, and ever since I added the Redcarpet gem, I get an error when I try to update a post.
Here is the error: undefined method 'update' for nil:NilClass
Here is my posts controller:
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
#post = Post.find_by_urlid(params[:urlid])
end
# GET /posts/new
def new
#post = Post.new
end
# GET /posts/1/edit
def edite
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(post_params)
#post.urlid = SecureRandom.urlsafe_base64
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Your Post was successfully created!' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Your Post was successfully updated!' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'You have successfully deleted the Post!' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find_by_urlid(params[:urlid])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:urlid, :author, :title, :body, :likes, :dislikes, :tags)
end
end
I've look at other posts, and their answers don't work. Any ideas?
Edit:
Server Log:
Started PATCH "/posts/sfqm5y99cbomqh4nmuxq5w" for 127.0.0.1 at 2014-10-31 13:05:07 -0700
Processing by PostsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"FRRgB2pI6GAQa6YL8KLZrUShshjjGd7+IXrLv1hTi5E=", "post"=>{"author"=>"Un3qual", "title"=>"First post", "body"=>" on new *dev* system **:D**", "likes"=>"9999", "dislikes"=>"0", "tags"=>""}, "commit"=>"Update Post", "urlid"=>"sfqm5y99cbomqh4nmuxq5w"}
Post Load (0.1ms) SELECT "posts".* FROM "posts" WHERE "posts"."urlid" = 'sfqm5y99cbomqh4nmuxq5w' LIMIT 1
Completed 500 Internal Server Error in 1ms
NoMethodError (undefined method `update' for nil:NilClass):
app/controllers/posts_controller.rb:46:in `block in update'
app/controllers/posts_controller.rb:45:in `update'
Rendered /Library/Ruby/Gems/2.0.0/gems/actionpack-4.1.4/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.4ms)
Rendered /Library/Ruby/Gems/2.0.0/gems/actionpack-4.1.4/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (0.6ms)
Rendered /Library/Ruby/Gems/2.0.0/gems/actionpack-4.1.4/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (0.6ms)
Rendered /Library/Ruby/Gems/2.0.0/gems/actionpack-4.1.4/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (8.9ms)
Started PATCH "/posts/sfqm5y99cbomqh4nmuxq5w" for 127.0.0.1 at 2014-10-31 15:42:18 -0700
Processing by PostsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"FRRgB2pI6GAQa6YL8KLZrUShshjjGd7+IXrLv1hTi5E=", "post"=>{"author"=>"Un3qual", "title"=>"First post", "body"=>" on new *dev* system **:D**", "likes"=>"9999", "dislikes"=>"0", "tags"=>""}, "commit"=>"Update Post", "urlid"=>"sfqm5y99cbomqh4nmuxq5w"}
Post Load (0.3ms) SELECT "posts".* FROM "posts" WHERE "posts"."urlid" = 'sfqm5y99cbomqh4nmuxq5w' LIMIT 1
Completed 500 Internal Server Error in 4ms
NoMethodError (undefined method `update' for nil:NilClass):
app/controllers/posts_controller.rb:46:in `block in update'
app/controllers/posts_controller.rb:45:in `update'
Rendered /Library/Ruby/Gems/2.0.0/gems/actionpack-4.1.4/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.4ms)
Rendered /Library/Ruby/Gems/2.0.0/gems/actionpack-4.1.4/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (0.6ms)
Rendered /Library/Ruby/Gems/2.0.0/gems/actionpack-4.1.4/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (0.6ms)
Rendered /Library/Ruby/Gems/2.0.0/gems/actionpack-4.1.4/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (10.2ms)
"Post.find_by_urlid(params[:urlid])" code has deprecated "find_by_" method. Rails 4 has deprecated "find_by_" methods. [Link]: http://edgeguides.rubyonrails.org/4_0_release_notes.html
Try Using: Post.find_by(urlid: params[:urlid]).
There is a typo error in "edite" method.
Based on the comments to your question, this is happening because there is no record with this urlid.
You should change your callback (before_action) filter like this.
def set_post
#post = Post.find_by(urlid: params[:urlid])
redirect_to posts_path, flash: {error: "The post does not exists"} if #post.nil?
end
This will redirect to the index of the posts, with an error message (you should have a div for errors flashing in your layout or your templates for it to appear).
If the #post exists, then it will relay to the action normally.
If you're not using any preloader which instantiate #post variable then it's the problem. For update action you should have:
def update
#post = Post.find params[:id]
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Your Post was successfully updated!' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
Tearing my hair out here. I have a brand model, this has_many projects and the projects belong_to the brand. I'm trying to create projects inside the brand but I'm running into the following error:
undefined method `projects_path'
Everything seems to be in order. Some of my code can be found below:
Routes
resources :brands do
resources :projects do
resources :ideas
end
end
Brands
<%= link_to 'Create New Project', new_brand_project_path(#brand) %>
The routing is working, as the link I'm sent to is brand/brand_id/projects/new - but this is where I get the error I mentioned earlier.
Update - The original problem was fixed, now when I save the project I'm getting the same error, but this time something is wrong with 'create'...
class ProjectsController < ApplicationController
# GET /projects
# GET /projects.json
def index
#projects = Project.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #projects }
end
end
# GET /projects/1
# GET /projects/1.json
def show
#project = Project.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #project }
end
end
# GET /projects/new
# GET /projects/new.json
def new
#brand = Brand.find(params[:brand_id])
#project = Project.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #project }
end
end
# GET /projects/1/edit
def edit
#project = Project.find(params[:id])
end
# POST /projects
# POST /projects.json
def create
#project = Project.new(params[:project])
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: 'Project was successfully created.' }
format.json { render json: #project, status: :created, location: #project }
else
format.html { render action: "new" }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
Add #brand = Brand.find(params[:brand_id]) to all your methods.
Remember the view comes back to the controller each time and can't remember what was set last time. The new method builds you the html form, but the create method is used to take the data and create the new record. But the create method doesn't know what you did in new, it can only work from the parameter data it was given.