Issues With Nested Resources being updated from parent show page - ruby

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 %>

Related

param is missing or the value is empty: category

Im trying to create a new Category based on the title of the 'grow' that im creating (for a garden management tool'
But Im getting the following error:
'param is missing or the value is empty: category'
[edit] this is how the code is fixed. As per the suggestion in the comments:
remove the #grow = Grow.new(grow_params.merge(category: Category.create(cat_params)))
and replace with #grow = Grow.new(grow_params)
and in the Grow model add
after_create do
Category.create(name: self.title)
end
and its fixed.
class GrowsController < ApplicationController
before_action :set_grow, only: [:show, :edit, :update, :destroy]
def index
#grows = Grow.all
end
def show
end
def new
#grow = Grow.new
end
def edit
end
def create
#grow = Grow.new(grow_params.merge(category: Category.create(cat_params)))
respond_to do |format|
if #grow.save
format.html { redirect_to #grow, notice: 'Grow was successfully created.' }
format.json { render :show, status: :created, location: #grow }
else
format.html { render :new }
format.json { render json: #grow.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /grows/1
# PATCH/PUT /grows/1.json
def update
respond_to do |format|
if #grow.update(grow_params)
format.html { redirect_to #grow, notice: 'Grow was successfully updated.' }
format.json { render :show, status: :ok, location: #grow }
else
format.html { render :edit }
format.json { render json: #grow.errors, status: :unprocessable_entity }
end
end
end
# DELETE /grows/1
# DELETE /grows/1.json
def destroy
#grow.destroy
respond_to do |format|
format.html { redirect_to grows_url, notice: 'Grow was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_grow
#grow = Grow.find(params[:id])
end
def cat_params
params.require(:category).permit(:name)
end
def grow_params
params.require(:grow).permit(:title, :notes, :category_id)
end
end
I simply want to pass in the grow.title to new category name
However im not sure how to implement it.
In your create method leave the statement to be
#grow = Grow.new(grow_params)
and in your Grow model, write an after_create callback
within which you create your Category like Category.create(name: self.title)

Issue with Nested Form Create - ActionController::UrlGenerationError in Calls#new

Hey all i'm building an app in Rails 4 Ruby 2.
I have recently nested a form In side of my Calls Show page I have added Ping (update) feature.
since I have completed the nesting... i can see the Ping in the show field the button to create a new Ping works, however i have since lost the ability to create a new call all together.
The Error I get is:
ActionController::UrlGenerationError in Calls#new
Showing /Users/TaurenLTD1/Desktop/TaurenLabs/PatrolProCAD/PatProCadApp/app/views/calls/_form.html.erb where line #459 raised:
No route matches {:action=>"new", :call_id=>nil, :controller=>"calls/pings"} missing required keys: [:call_id]
Extracted source (around line #459):
457
458
459
460
461
462
</div>
<div class="panel panel-info" id="update-pnl">
<div class="panel-heading" id="update-top"><center><h4><strong id="update-txt">Live Updates - Found In View Call</strong> <%= link_to "Add Update", new_call_ping_path(#call), class: 'btn btn-primary btn-sm', :id => 'add-update' %> </h4></center></div>
</div>
<div class="new-wrapper">
<div class="panel panel-warning" id="location-box">
Trace of template inclusion: app/views/calls/new.html.erb
My Routes rb file:
Rails.application.routes.draw do
devise_for :users, controllers: { registrations: 'registrations' }
devise_scope :user do
authenticated :user do
root 'calls#index', as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
end
resources :sites
resources :calls do
resources :pings, except: [:index], controller: 'calls/pings'
collection do
get 'history'
end
member do
patch :update_unit_on_scene
patch :update_unit_clear
patch :update_unit2_os
patch :update_unit2_cl
patch :update_unit3_os
patch :update_unit3_cl
patch :update_unit4_os
patch :update_unit4_cl
end
end
end
my calls/pings controller: (The update form accessed through the shot.html.erb page)
class Calls::PingsController < ApplicationController
before_action :set_ping, only: [:show, :edit, :update, :destroy]
# GET /pings
# GET /pings.json
def index
#pings = Ping.all
end
# GET /pings/1
# GET /pings/1.json
def show
end
# GET /pings/new
def new
#call = Call.find(params[:call_id])
#ping = Ping.new
end
# GET /pings/1/edit
def edit
end
# POST /pings
# POST /pings.json
def create
#call = Call.find(params[:call_id])
#ping = Ping.new(ping_params)
#ping.call = #call
respond_to do |format|
if #ping.save
format.html { redirect_to #call, notice: 'Call update has been successfully added to call.' }
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 /pings/1
# PATCH/PUT /pings/1.json
def update
respond_to do |format|
if #ping.update(ping_params)
format.html { redirect_to #ping, notice: 'Ping was successfully updated.' }
format.json { render :show, status: :ok, location: #ping }
else
format.html { render :edit }
format.json { render json: #ping.errors, status: :unprocessable_entity }
end
end
end
# DELETE /pings/1
# DELETE /pings/1.json
def destroy
#ping.destroy
respond_to do |format|
format.html { redirect_to pings_url, notice: 'Ping was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_ping
#ping = Ping.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def ping_params
params.require(:ping).permit(:priority, :msg, :received, :call_id)
end
end
and this is my calls controller (The original form)
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'}
#approved_calls = #calls.select{|x| x.status == "APPROVED"}
#on_scene = #calls.select{|x| x.status == "ACTIVE"}
end
# GET /calls/1
# GET /calls/1.json
def show
#unit_2 = #call.unit_2
#unit_3 = #call.unit_3
#unit_4 = #call.unit_4
#call = Call.find(params[:id])
#pings = #call.pings
end
# GET /calls/new
def new
#call = Call.new
#unit_2 = #call.unit_2
#unit_3 = #call.unit_3
#unit_4 = #call.unit_4
#pings = #call.pings
end
# GET /calls/1/edit
def edit
#call = Call.find(params[:id])
end
# POST /calls
# POST /calls.json
def create
#call = Call.new(call_params)
#call = Call.find(params[:call_id])
#ping = Ping.new(ping_params)
#ping.call = #call
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
### Custom View for Call History
def history
#approved_calls = Call.where(status: 'APPROVED')
end
### Custom Calls for Unit 1-4 On Scene and Call Buttons ###
def update_unit_on_scene
#call = Call.find(params[:id])
#call.unit_on_scene = DateTime.now
#call.status = "ACTIVE"
#call.save
respond_to do |format|
if #call.save
format.html { redirect_to #call, notice: "On Scene Time Successfully Updated. - You Are Now Logged Out Of Service" }
else
format.html { render action: 'edit' }
end
end
end
def update_unit_clear
#call = Call.find(params[:id])
#call.unit_clear = DateTime.now
#call.status = "CLEAR"
#call.save
respond_to do |format|
if #call.save
format.html { redirect_to #call, notice: "Scene Clear Time Successfully Updated. - You Are Now Logged In Service" }
else
format.html { render action: 'edit' }
end
end
end
def update_unit2_os
#call = Call.find(params[:id])
#call.unit2_os = DateTime.now
#call.save
respond_to do |format|
if #call.save
format.html { redirect_to #call, notice: "On Scene Time Successfully Updated. - You Are Now Logged Out Of Service" }
else
format.html { render action: 'edit' }
end
end
end
def update_unit2_cl
#call = Call.find(params[:id])
#call.unit2_cl = DateTime.now
#call.save
respond_to do |format|
if #call.save
format.html { redirect_to #call, notice: "Scene Clear Time Successfully Updated. - You Are Now Logged In Service" }
else
format.html { render action: 'edit' }
end
end
end
def update_unit3_os
#call = Call.find(params[:id])
#call.unit3_os = DateTime.now
#call.save
respond_to do |format|
if #call.save
format.html { redirect_to #call, notice: "On Scene Time Successfully Updated. - You Are Now Logged Out Of Service" }
else
format.html { render action: 'edit' }
end
end
end
def update_unit3_cl
#call = Call.find(params[:id])
#call.unit3_cl = DateTime.now
#call.save
respond_to do |format|
if #call.save
format.html { redirect_to #call, notice: "Scene Clear Time Successfully Updated. - You Are Now Logged In Service" }
else
format.html { render action: 'edit' }
end
end
end
def update_unit4_os
#call = Call.find(params[:id])
#call.unit4_os = DateTime.now
#call.save
respond_to do |format|
if #call.save
format.html { redirect_to #call, notice: "On Scene Time Successfully Updated. - You Are Now Logged Out Of Service" }
else
format.html { render action: 'edit' }
end
end
end
def update_unit4_cl
#call = Call.find(params[:id])
#call.unit4_cl = DateTime.now
#call.save
respond_to do |format|
if #call.save
format.html { redirect_to #call, notice: "Scene Clear Time Successfully Updated. - You Are Now Logged In Service" }
else
format.html { render action: 'edit' }
end
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(:call_time, :status, :primary_type, :secondary_type, :site, :address, :unit_1, :unit_2, :unit_3, :unit_4, :call_details, :unit_on_scene, :unit_clear, :call_num, :site_id, :user_id, :unit2_os, :unit2_cl, :unit3_os, :unit3_cl, :unit4_os, :unit4_cl)
end
end
I have no idea where i've gone wrong as i have never nested before and after going back trough a few tutorials on nesting i am still stuck.
Any help is greatly appreciated!
Thanks in advance!
EDIT #1:
Rake Routes Output for the affected scaffolds:
Prefix Verb URI Pattern Controller#Action
call_pings POST /calls/:call_id/pings(.:format) calls/pings#create
new_call_ping GET /calls/:call_id/pings/new(.:format) calls/pings#new
edit_call_ping GET /calls/:call_id/pings/:id/edit(.:format) calls/pings#edit
call_ping GET /calls/:call_id/pings/:id(.:format) calls/pings#show
PATCH /calls/:call_id/pings/:id(.:format) calls/pings#update
PUT /calls/:call_id/pings/:id(.:format) calls/pings#update
DELETE /calls/:call_id/pings/:id(.:format) calls/pings#destroy
history_calls GET /calls/history(.:format) calls#history
update_unit_on_scene_call PATCH /calls/:id/update_unit_on_scene(.:format) calls#update_unit_on_scene
update_unit_clear_call PATCH /calls/:id/update_unit_clear(.:format) calls#update_unit_clear
update_unit2_os_call PATCH /calls/:id/update_unit2_os(.:format) calls#update_unit2_os
update_unit2_cl_call PATCH /calls/:id/update_unit2_cl(.:format) calls#update_unit2_cl
update_unit3_os_call PATCH /calls/:id/update_unit3_os(.:format) calls#update_unit3_os
update_unit3_cl_call PATCH /calls/:id/update_unit3_cl(.:format) calls#update_unit3_cl
update_unit4_os_call PATCH /calls/:id/update_unit4_os(.:format) calls#update_unit4_os
update_unit4_cl_call PATCH /calls/:id/update_unit4_cl(.:format) calls#update_unit4_cl
update_primary_resp_1_call PATCH /calls/:id/update_primary_resp_1(.:format) calls#update_primary_resp_1
calls GET /calls(.:format) calls#index
POST /calls(.:format) calls#create
new_call GET /calls/new(.:format) calls#new
edit_call GET /calls/:id/edit(.:format) calls#edit
call GET /calls/:id(.:format) calls#show
PATCH /calls/:id(.:format) calls#update
PUT /calls/:id(.:format) calls#update
DELETE /calls/:id(.:format) calls#destroy
EDIT #2: Rails Server Output when clicking new call button:
tarted GET "/calls/new" for ::1 at 2015-11-22 23:26:21 -0700
Processing by CallsController#new as HTML
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 3]]
Rendered calls/_form.html.erb (11.8ms)
Rendered calls/new.html.erb within layouts/application (13.4ms)
Completed 500 Internal Server Error in 19ms (ActiveRecord: 0.2ms)
ActionView::Template::Error (No route matches {:action=>"new", :call_id=>nil, :controller=>"calls/pings"} missing required keys: [:call_id]):
456: </table>
457: </div>
458: <div class="panel panel-info" id="update-pnl">
459: <div class="panel-heading" id="update-top"><center><h4><strong id="update-txt">Live Updates - Found In View Call</strong> <%= link_to "Add Update", new_call_ping_path(#call), class: 'btn btn-primary btn-sm', :id => 'add-update' %> </h4></center></div>
460: </div>
461: <div class="new-wrapper">
462: <div class="panel panel-warning" id="location-box">
app/views/calls/_form.html.erb:459:in `block in _app_views_calls__form_html_erb___1493490319796568156_70162629771600'
app/views/calls/_form.html.erb:1:in `_app_views_calls__form_html_erb___1493490319796568156_70162629771600'
app/views/calls/new.html.erb:3:in `_app_views_calls_new_html_erb___3696559492073097692_70162629705900'
Edit #3: Error when using new_call_ping_path
ActionController::UrlGenerationError in Calls#edit
Showing /Users/TaurenLTD1/Desktop/TaurenLabs/PatrolProCAD/PatProCadApp/app/views/calls/_form.html.erb where line #459 raised:
No route matches {:action=>"new", :controller=>"calls/pings", :id=>"3"} missing required keys: [:call_id]
</div>
<div class="panel panel-info" id="update-pnl">
<div class="panel-heading" id="update-top"><center><h4><strong id="update-txt">Live Updates - Found In View Call</strong> <%= link_to "Add Update", new_call_ping_path, class: 'btn btn-primary btn-sm', :id => 'add-update' %> </h4></center></div>
</div>
<div class="new-wrapper">
<div class="panel panel-warning" id="location-box">
I would try running rake routes from the command line and see if any routes rails generates from routes.rb match your error.
Posting relevant info from running rake routes may be useful.
EDIT:
Try just new_call_ping_path on line 459 instead of new_call_ping_path(#call).
EDIT 2:
Try new_call_ping_path(call_id: #call.id). The problem here is the URL generator is expecting the call_id since in routes.rb declares the format as follows: new_call_ping GET /calls/:call_id/pings/new(.:format).
If you update pings for call in call controller then you have to do this:-
Model Call.rb
has_many :pings
accepts_nested_attributes_for :pings
Permit nested attributes in call_params method and change new and create method in calls_contoller.rb like:-
def new
#call = Call.new
#unit_2 = #call.unit_2
#unit_3 = #call.unit_3
#unit_4 = #call.unit_4
#pings = #call.pings.build
end
def create
#call = Call.new(call_params)
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
private
def call_params
params.require(:call).permit(:call_time, :status, :primary_type, :secondary_type, :site, :address, :unit_1, :unit_2, :unit_3, :unit_4, :call_details, :unit_on_scene, :unit_clear, :call_num, :site_id, :user_id, :unit2_os, :unit2_cl, :unit3_os, :unit3_cl, :unit4_os, :unit4_cl,
pings_attributes: [:id, :priority, :msg, :received])
end
If you want to add pings for call from ping controller then you can add by doing this:-
def new
#call = Call.find(params[:call_id])
#pings = #call.pings.build
end
def create
#call = Call.find(params[:call_id])
respond_to do |format|
if #call.update_attributes(call_params)
format.html { redirect_to #call, notice: 'Call update has been successfully added to call.' }
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
private
def call_params
params.require(:call).permit(pings_attributes: [:id, :priority, :msg, :received])
end
So i solved this little problem.. It was actually a pretty ridiculous issue.. Whe i created the nested controller, I had the controller open when I dragged and dropped the file into the calls folder under controllers..
What happened was although i was pointing to the calls/pings controller and even though rake routes was showing the appropriate routes, rails was still looking at the original pings controller..
as soon as i deleted the duplicate controller, all fell into place and began to work just fine.
Thanks all for your had work on trying to resolve this!

NoMethodError Rails 4 App -> Nested attribute issue

I am working on a Rails 4 App, one of my modules is a general patrol report in which a user creates a report based on his / her shift shift start / stop. after the report is created they have the option to go back into the report view and add a patrol report.
Every thing is working up to the gen_rep_ent form submission.
The specific error I get is:
undefined method `general_report=' for #<GenRepEnt:0x007f871d9ea150>
followed by:
def create
#general_report = GeneralReport.find(params[:general_report_id])
#gen_rep_ent = GenRepEnt.new(gen_rep_ent_params)
#gen_rep_ent.general_report = #gen_rep_ent <-- Problem Line
respond_to do |format|
if #gen_rep_ent.save
format.html { redirect_to #general_report, notice: 'General Report Entry was successfully created.' }
format.json { render :show, status: :created, location: #general_report}
else
format.html { render :new }
format.json { render json: #general_report.errors, status: :unprocessable_entity }
end
end
end
It is the 3rd line that is causing the issue here.
My general_report model has the following relationship:
has_many :gen_rep_ents, dependent: :destroy
My Routes File looks Like:
Rails.application.routes.draw do
resources :mobile_alarm_reports
resources :mobile_incident_reports
resources :static_incident_reports
resources :general_reports do
resources :gen_rep_ents, except: [:index], controller: 'general_reports/gen_rep_ents'
end
resources :visitor_parkings
resources :residents
resources :sites
devise_for :users, controllers: { registrations: "registrations" }
# Adds Static Pages
root 'home#index'
get 'home/about'
get 'home/contact'
get 'home/pricing'
My show file looks like:
<% #gen_rep_ents.each do |gen_rep_ent| %>
<table>
<thead>
<tr>
<th>Time</th>
<th>Report</th>
</tr>
</thead>
<tbody>
<tr>
<td><%= gen_rep_ent.time %></td>
<td><%= gen_rep_ent.report %></td>
</tr>
</tbody>
<% end %>
</table>
gen_rep_ents_controller.rb: <-- The nested Item
class GeneralReports::GenRepEntsController < ApplicationController
before_action :set_gen_rep_ent, only: [:show, :edit, :update, :destroy]
# GET /gen_rep_ents
# GET /gen_rep_ents.json
def index
#gen_rep_ents = GenRepEnt.all
end
# GET /gen_rep_ents/1
# GET /gen_rep_ents/1.json
def show
end
# GET /gen_rep_ents/new
def new
#general_report = GeneralReport.find(params[:general_report_id])
#gen_rep_ent = GenRepEnt.new
end
# GET /gen_rep_ents/1/edit
def edit
end
# POST /gen_rep_ents
# POST /gen_rep_ents.json
def create
#general_report = GeneralReport.find(params[:general_report_id])
#gen_rep_ent = GenRepEnt.new(gen_rep_ent_params)
#gen_rep_ent.general_report = #gen_rep_ent
respond_to do |format|
if #gen_rep_ent.save
format.html { redirect_to #general_report, notice: 'General Report Entry was successfully created.' }
format.json { render :show, status: :created, location: #general_report}
else
format.html { render :new }
format.json { render json: #general_report.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /gen_rep_ents/1
# PATCH/PUT /gen_rep_ents/1.json
def update
respond_to do |format|
if #gen_rep_ent.update(gen_rep_ent_params)
format.html { redirect_to #gen_rep_ent, notice: 'General Report Entry was successfully updated.' }
format.json { render :show, status: :ok, location: #gen_rep_ent }
else
format.html { render :edit }
format.json { render json: #gen_rep_ent.errors, status: :unprocessable_entity }
end
end
end
# DELETE /gen_rep_ents/1
# DELETE /gen_rep_ents/1.json
def destroy
#gen_rep_ent.destroy
respond_to do |format|
format.html { redirect_to gen_rep_ents_url, notice: 'General Report Entry was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_gen_rep_ent
#gen_rep_ent = GenRepEnt.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def gen_rep_ent_params
params.require(:gen_rep_ent).permit(:time, :report, :general_report)
end
end
The general_reports_controller: <-- Parent Item
class GeneralReportsController < ApplicationController
before_action :set_general_report, only: [:show, :edit, :update, :destroy]
# GET /general_reports
# GET /general_reports.json
def index
#general_reports = GeneralReport.all
end
# GET /general_reports/1
# GET /general_reports/1.json
def show
#general_report = GeneralReport.find(params[:id])
#gen_rep_ents = #general_report.gen_rep_ents
end
# GET /general_reports/new
def new
#general_report = GeneralReport.new
end
# GET /general_reports/1/edit
def edit
end
# POST /general_reports
# POST /general_reports.json
def create
#general_report = GeneralReport.new(general_report_params)
respond_to do |format|
if #general_report.save
format.html { redirect_to #general_report, notice: 'General report was successfully created.' }
format.json { render :show, status: :created, location: #general_report }
else
format.html { render :new }
format.json { render json: #general_report.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /general_reports/1
# PATCH/PUT /general_reports/1.json
def update
respond_to do |format|
if #general_report.update(general_report_params)
format.html { redirect_to #general_report, notice: 'General report was successfully updated.' }
format.json { render :show, status: :ok, location: #general_report }
else
format.html { render :edit }
format.json { render json: #general_report.errors, status: :unprocessable_entity }
end
end
end
# DELETE /general_reports/1
# DELETE /general_reports/1.json
def destroy
#general_report.destroy
respond_to do |format|
format.html { redirect_to general_reports_url, notice: 'General report was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_general_report
#general_report = GeneralReport.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def general_report_params
params.require(:general_report).permit(:user_id, :site_id, :date, :shift_start, :shift_end, :gp_number)
end
end
I am not too sure where I'm going wrong with this as I have reviewed the tutorial over and over, and it all matches from what I can see.
EDIT # 1
my GenRepEnt model looks like:
class GenRepEnt < ActiveRecord::Base
belongs_to :general_report
end
EDIT # 2
After performing the migration and adding belongs_to :general_report to the model I get the following error:
ActiveRecord::AssociationTypeMismatch in
GeneralReports::GenRepEntsController#create
Looks like you are trying to set general_report on an instance of a GenRepEnt class but that method doesn't exist. This is likely because the association was not set up in the GenRepEnt model.
In the model gen_rep_ent.rb add the following association:
belongs_to :general_report
After you declare this association Rails will define a few methods on each instance of GenRepEnt including:
general_report
general_report=
You will also need to generate a migration that will add a new column, general_report_id, to the gen_rep_ents table.
In your terminal run rails g migration AddGeneralReportRefToGenRepEnts general_report:references
This should generate a migration that looks something like this:
class AddGeneralReportRefToGenRepEnts < ActiveRecord::Migration
def change
add_reference :gen_rep_ents, :general_report, index: true, foreign_key: true
end
end
Next, run the migration using rake db:migrate and restart your app.
Read more about the belongs_to association here.

Getting syntax error, unexpected keyword_end, expecting end-of-input

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

Password can't be blank - User scaffold

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.

Resources