I've just generated my User scaffold and I'm now getting an error with 'Password can't be blank' even though I've filled out all the fields. I'm confused because my rake tests are passing, so not sure where the error is?
User Model:
class User < ActiveRecord::Base
validates :name, presence: true, uniqueness: true
has_secure_password
end
And my user controller:
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
# GET /users
# GET /users.json
def index
#users = User.order(:name)
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
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to users_url, notice: "User #{#user.name} was successfully created." }
format.json { render action: 'show', status: :created, location: #user }
else
format.html { render action: '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 users_url, notice: "User #{#user.name} was successfully updated." }
format.json { head :no_content }
else
format.html { render action: '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 }
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_digest)
end
end
If you need more code submitted, just let me know. I'm working with Rails 4.
Would be nice to see the server logs when you submit the form, something tells me you don't require the right parameters, from your form there should be: password and password_confirmation but in controller you require password_digest for some reason:
def user_params
params.require(:user).permit(:name, :password_digest)
end
it should be:
def user_params
params.require(:user).permit(:name, :password, :password_confirmation)
end
and password_digest should be updated not via params.
Related
How do I go about making this code block dry?
I understand that dry means dont repeat yourself but I don't see any obvious opportunity for refactoring.
Index, show, edit, and create seem like basic/necessary methods. They appear to be pretty dry to me.
The methods after I am not sure about.
I haven't tried anything other than googling so far.
class UsersController < ApplicationController
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def edit
#user = User.find(params[:id])
end
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
Slack.notify_channel
end
def update
#user = User.find(params[:id])
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
Slack.notify_channel
end
def destroy
#user = User.find(params[:id])
#user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
Slack.notify_channel
end
private
def user_params
params.require(:user).permit(:username, :email)
end
end
There is no rails backend attached to this code snippet. I am assuming it is just theoretical - wanting us to refactor the code to make it shorter.
IMHO you can do something like that.
class UsersController < ApplicationController
include ExceptionHandling
before_action :load_user, only: [:show, :edit, :update, :destroy]
after_action :slack_notify_channel, only: [:create, :update, :destroy]
def index
#users = User.all
end
def new
#user = User.new
end
def create
#user = User.create!(user_params)
respond_to do |format|
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
end
end
def update
#user.update!(user_params)
respond_to do |format|
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { render :show, status: :ok, location: #user }
end
end
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
def load_user
#user = User.find(params[:id])
end
def slack_notify_channel
Slack.notify_channel
end
def user_params
params.require(:user).permit(:username, :email)
end
end
I would recommend you to create a concern to manage exceptions and render each specific error by exception. Then you can avoid having two ways in each action to render a good and bad case.
I have to guess a bit about what's in your ApplicationController and User classes. But the obviously repeated code is #user = User.find(params[:id]). Your show and edit methods both just run this line. So, they do exactly the same thing, which they oughtn't to do. One method for one thing.
Also, once you resolve show and edit into a single method, your create, update and destroy methods should call it instead of repeating the line.
Next, I wouldn't use new as a method name, since it is already used by BasicObject::new. I tested a few things and it gets pretty unclear:
class Test
attr_reader :test
def initialize
#test = 'test'
end
end
class Test2
attr_reader :test2
def new
p 'test2new'
#test2 = Test.new
end
end
testx = Test2.new
p testx.new.test
p testx.test2.test
=> "test2new"
=> "test"
=> "test"
It takes extra effort to see when you're calling your own new method and when you're calling BasicObject::new. So, I'd change that to new_user or something, if you even need it at all — I don't see why you need both it and your create method. (If you don't need it, get rid of it.)
Finally, #user = User.find(params[:id]) doesn't imply either showing or editing, so understanding what you're trying to do and coming up with a name that reflects it (e.g. set_user_id) is something that ought to be done as well.
Im building out an app in Rails 4 Ruby 2
Background:
I have a parent scaffold named "Calls" I then have a child scaffold named "Respondings". What I am attempting to achieve here is to have the ability to update items in the "Respondings" table from the "Calls" show.html.erb by way of a custom button click. (Shown below)
My routes look like so:
resources :calls do
resources :respondings, except: [:index], controller: 'calls/respondings' do
member do
patch :unit_responding_update
end
end
resources :pings, except: [:index], controller: 'calls/pings'
resources :agencies, except: [:index], controller: 'calls/agencies'
resources :incidents, except: [:index], controller: 'calls/incidents'
resources :complainants, except: [:index], controller: 'calls/complainants'
end
end
The patch: unit_respondings_update is what custom method that will update the table when pressed.
The Custom Def Rake output Here:
unit_responding_update_call_responding PATCH /calls/:call_id/respondings/:id/unit_responding_update(.:format) calls/respondings#unit_responding_update
My problem is that i have tried to place this in both the calls_controller.rb and the calls/respondings_controller.rb both to no avail. Listed below are the two controllers in their entirety. the other BIG Problem i am having is generating the path in the button to have this read and perform the function.
Parent Controller "Calls_controller"
class CallsController < ApplicationController
before_action :set_call, only: [:show, :edit, :update, :destroy]
# GET /calls
# GET /calls.json
def index
#calls = Call.all
#active_calls = #calls.select{ |x| x.status == 'ACTIVE' }
#pending_calls = #calls.select{ |x| x.status == 'PENDING'}
#clear_calls = #calls.select{ |x| x.status == 'CLEAR'}
end
# GET /calls/1
# GET /calls/1.json
def show
#call = Call.find(params[:id])
## Responding Nested
#respondings = #call.respondings
## Ping Nested
#pings = #call.pings
## Agency Nested
#agencies = #call.agencies
## Incidents Nested
#incidents = #call.incidents
## Complainants Nested
#complainants = #call.complainants
end
# GET /calls/new
def new
#call = Call.new
end
# GET /calls/1/edit
def edit
end
# POST /calls
# POST /calls.json
def create
#call = Call.new(call_params)
#call.status = "PENDING"
respond_to do |format|
if #call.save
format.html { redirect_to #call, notice: 'Call was successfully created.' }
format.json { render :show, status: :created, location: #call }
else
format.html { render :new }
format.json { render json: #call.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /calls/1
# PATCH/PUT /calls/1.json
def update
respond_to do |format|
if #call.update(call_params)
format.html { redirect_to #call, notice: 'Call was successfully updated.' }
format.json { render :show, status: :ok, location: #call }
else
format.html { render :edit }
format.json { render json: #call.errors, status: :unprocessable_entity }
end
end
end
# DELETE /calls/1
# DELETE /calls/1.json
def destroy
#call.destroy
respond_to do |format|
format.html { redirect_to calls_url, notice: 'Call was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_call
#call = Call.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def call_params
params.require(:call).permit(:site_id, :call_number, :call_type, :call_type_other, :call_details, :user_id, :status)
end
end
Child Controller "calls/respondings_controller": Currently Where the Custom Method is found:
class Calls::RespondingsController < ApplicationController
#before_action :set_responding, only: [:show, :edit, :update, :destroy]
# GET /respondings
# GET /respondings.json
def index
#respondings = Responding.all
end
# GET /respondings/1
# GET /respondings/1.json
def show
end
# GET /respondings/new
def new
#call = Call.find(params[:call_id])
#responding = Responding.new
end
# GET /respondings/1/edit
def edit
end
# POST /respondings
# POST /respondings.json
def create
#call = Call.find(params[:call_id])
#responding = Responding.new(responding_params)
#responding.call = #call
respond_to do |format|
if #responding.save
format.html { redirect_to #call, notice: 'Responding was successfully created.' }
format.json { render :show, status: :created, location: #call }
else
format.html { render :new }
format.json { render json: #call.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /respondings/1
# PATCH/PUT /respondings/1.json
def update
respond_to do |format|
if #responding.update(responding_params)
format.html { redirect_to #responding, notice: 'Responding was successfully updated.' }
format.json { render :show, status: :ok, location: #responding }
else
format.html { render :edit }
format.json { render json: #responding.errors, status: :unprocessable_entity }
end
end
end
# DELETE /respondings/1
# DELETE /respondings/1.json
def destroy
#call = Call.find(params[:call_id])
#responding = Responding.find(params[:id])
if #responding.destroy
flash[:notice] = "Successfully removed unit from call."
redirect_to #call
else
flash[:error] = "There was an error removing this responder from this call."
end
end
#Custom Controller Calls
def unit_responding_update
#call = Call.find(params[:call_id])
#responding = Responding.find(params[:id])
#responding.responding_tme = DateTime.now
#responding.responding = "true"
#responding.on_scene = "false"
#responding.clear = "false"
#responding.status = "RESPONDING"
#responding.save!
respond_to do |format|
if #responding.save
format.html { redirect_to #call, notice: "Responding time successfully updated. Your status - RESPONDING" }
else
format.html { render action: 'edit' }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_responding
#responding = Responding.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def responding_params
params.require(:responding).permit(:call_id, :user_id, :responding_tme, :on_scene_tme, :clear_tme, :responding, :on_scene, :clear, :status)
end
end
If you need more information please don't hesitate to ask! i am at a standstill until this is resolved! ( or for access to my Git where this is stored for full context)
Thanks in advance to everyone!
EDIT # 1: -- Adds Calls / Respondings Model Relations
Model Relations For Call
class Call < ActiveRecord::Base
has_many :respondings, dependent: :destroy
end
Model Relations for Responding
class Responding < ActiveRecord::Base
has_many :incidents
belongs_to :call
end
So the Fix to this problem was soley in the routes file.. it turns out I was missing and end.. After changing my routes file to the following, it solved the initial problem altogether.
resources :calls do
resources :respondings, except: [:index], controller: 'calls/respondings' do
member do
patch :unit_responding_update
end
end
resources :pings, except: [:index], controller: 'calls/pings'
resources :agencies, except: [:index], controller: 'calls/agencies'
resources :incidents, except: [:index], controller: 'calls/incidents'
resources :complainants, except: [:index], controller: 'calls/complainants'
end
end
Once the routes were fixed I used the following link:
<%= link_to "Responding", unit_responding_update_call_responding_path(call_id: #call.id, id: #respondings.first.id), method: :patch %>
Before I begin, let me say that I have two different devise user models.
I began removing the unnecessary methods from the scaffold_controller, because devise handles certain actions.
I'm trying to route to the current_user profile page, but I get an error every time I try to add the link in my navbar <%= 'My Profile', current_user %> doesn't work in this case. I plan to setup the associations as soon as I finish hooking up these controllers.
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy]
# GET /profiles
# GET /profiles.json
def index
#profiles = Profile.all
end
# GET /profiles/1
# GET /profiles/1.json
def show
#user = User.find(params[:id])
respond_to do |format|
format.html
format.json {render :json => #user }
end
end
# GET /profiles/1/edit
def edit
end
# PATCH/PUT /profiles/1
# PATCH/PUT /profiles/1.json
def update
respond_to do |format|
if #profile.update(profile_params)
format.html { redirect_to #profile, notice: 'Profile was successfully updated.' }
format.json { render :show, status: :ok, location: #profile }
else
format.html { render :edit }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# DELETE /profiles/1
# DELETE /profiles/1.json
def destroy
#profile.destroy
respond_to do |format|
format.html { redirect_to profiles_url, notice: 'Profile was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_profile
#profile = Profile.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def profile_params
params[:profile]
end
end
profiles GET /profiles(.:format) profiles#index
POST /profiles(.:format) profiles#create
new_profile GET /profiles/new(.:format) profiles#new
edit_profile GET /profiles/:id/edit(.:format) profiles#edit
profile GET /profiles/:id(.:format) profiles#show
PATCH /profiles/:id(.:format) profiles#update
PUT /profiles/:id(.:format) profiles#update
DELETE /profiles/:id(.:format) profiles#destroy
Assuming (such as bad thing to do), that you have already created the profile while creating the user ( since there is no create action in the controller ) and that a profile belongs_to a user, then this should work:
<%= link_to "My Profile", current_user.profile %>
Generally, I would get my associations set up properly before I even look at the controllers.
This was working until 5 minutes ago and I'm not sure what I edited that screwed things up. I've rolled back to the version I had before and I'm still getting the error. I've gone line by line to make sure I don't have an extra end and unless I'm blind, each end matches up with a def.
Specific Error:
SyntaxError in CompaniesController#index
/projects/TSO/app/controllers/companies_controller.rb:93: syntax error, unexpected keyword_end, expecting end-of-input
Here's my code:
class CompaniesController < ApplicationController
before_action :set_company, only: [:show, :edit, :update, :destroy]
before_action :authenticate_contact!, only: [:index, :show, :edit, :update, :destroy]
# GET /companies
# GET /companies.json
def index
#company = Company.find(#company.id, include: :contacts, include: :subscriptions)
end
# GET /companies/1
# GET /companies/1.json
def show
#company = Company.find(#company.id, include: :contacts, include: :subscriptions)
end
# GET /companies/new
def new
#company = Company.new
#company.contacts.build
end
# GET /companies/1/edit
def edit
end
# POST /companies
# POST /companies.json
def create
#company = Company.new(company_params)
respond_to do |format|
if #company.save
sign_in(#company.contacts.first)
format.html { redirect_to #company, notice: 'Company was successfully created.' }
format.json { render action: 'show', status: :created, location: #company }
else
format.html { render action: 'new' }
format.json { render json: #company.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /companies/1
# PATCH/PUT /companies/1.json
def update
respond_to do |format|
if #company.update(company_params)
format.html { redirect_to #company, notice: 'Company was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #company.errors, status: :unprocessable_entity }
end
end
end
# DELETE /companies/1
# DELETE /companies/1.json
def destroy
#company.destroy
respond_to do |format|
format.html { redirect_to companies_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_company
if params[:id].nil?
#company = Company.find(current_contact.company_id)
else
#company = Company.find(params[:id])
end
end
# Never trust parameters from the scary internet, only allow the white list through.
def company_params
params.require(:company).permit(:name, :legal_entity, :KVK_number, :VAT_number, contacts_attributes:[:first_name, :last_name, :address, :phone, :email, :postcode, :password] )
end
end
end
No idea on what I'm doing wrong now.
Your indentation is messed up and you've added an extra end in there because of it.
The private declaration should be at the same level as class.
A general template looks like:
class Example
def method
# ...
end
private
def private_method
end
end
What you have:
class Example
def method
# ...
end
private
def private_method
end
end
end
I'm currently learning ruby, and i have an application where a user enters:
:name
:menu
:rsvp
They are all entered as a reply
I want to be able to get a count of how many people are currently added and display this on the index page. How would i go about getting a count to go over how many items are added to the database thus far?
Reply.rb
class Reply < ActiveRecord::Base
attr_accessible :menu, :name, :rsvp, :user_id
belongs_to :user
end
User.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me,
:first_name, :last_name, :profile_name
# attr_accessible :title, :body
has_many :replies
def full_name
first_name + " " + last_name
end
end
Replies Controller
class RepliesController < ApplicationController
# GET /replies
# GET /replies.json
def index
#replies = Reply.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #replies }
end
end
# GET /replies/1
# GET /replies/1.json
def show
#reply = Reply.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #reply }
end
end
# GET /replies/new
# GET /replies/new.json
def new
#reply = Reply.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #reply }
end
end
# GET /replies/1/edit
def edit
#reply = Reply.find(params[:id])
end
# POST /replies
# POST /replies.json
def create
#reply = Reply.new(params[:reply])
respond_to do |format|
if #reply.save
format.html { redirect_to #reply, notice: 'Reply was successfully created.' }
format.json { render json: #reply, status: :created, location: #reply }
else
format.html { render action: "new" }
format.json { render json: #reply.errors, status: :unprocessable_entity }
end
end
end
# PUT /replies/1
# PUT /replies/1.json
def update
#reply = Reply.find(params[:id])
respond_to do |format|
if #reply.update_attributes(params[:reply])
format.html { redirect_to #reply, notice: 'Reply was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #reply.errors, status: :unprocessable_entity }
end
end
end
# DELETE /replies/1
# DELETE /replies/1.json
def destroy
#reply = Reply.find(params[:id])
#reply.destroy
respond_to do |format|
format.html { redirect_to replies_url }
format.json { head :no_content }
end
end
end
I hope this information is helpful.
To get the User count:
User.count
In your controller, it's best to put this in an instance variable:
#user_count = User.count
To show it on a typical ERR view:
<%= #user_count %>
All the typical ActiveRecord models, controllers, and views work like this.