Dynamic Dropdown SelectBox in Rails Issue - ruby

I'm working on a project in rails 4 where I am creating some dynamic drop downs. Below is all the code i have done for this dropdown. The drop downs are appearing, however not saving to the table and wont show up in the Show (and yes I have the proper ruby ie. <%= #reports.site_id %>.
I am not sure what to do from here and I am a bit of a rails noob, but have worked through tutorials and classes on the language.
My Form Select Box Looks Like this:
`<%= collection_select( :site, :site_id, Site.all, :id, :site_call_sign, {}, { :multiple => false %>`
The above select box dose get data from the site table but wont save that data to the reports table??`
My Controller looks like this:
class ReportsController < ApplicationController
before_action :set_report, only: [:show, :edit, :update, :destroy]
# GET /reports
# GET /reports.json
def index
#search = ReportDateSearch.new(params[:search])
#reports = #search.scope
#reports = Report.all
# Adds CSV Downloader to Residents
respond_to do |format|
format.html
format.csv { render text: #reports.to_csv }
end
end
# GET /reports/1
# GET /reports/1.json
def show
end
# GET /reports/new
def new
#report = Report.new
end
# GET /reports/1/edit
def edit
end
# POST /reports
# POST /reports.json
def create
#report = Report.new(report_params)
respond_to do |format|
if #report.save
format.html { redirect_to #report, notice: 'Report was successfully created.' }
format.json { render :show, status: :created, location: #report }
else
format.html { render :new }
format.json { render json: #report.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /reports/1
# PATCH/PUT /reports/1.json
def update
respond_to do |format|
if #report.update(report_params)
format.html { redirect_to #report, notice: 'Report was successfully updated.' }
format.json { render :show, status: :ok, location: #report }
else
format.html { render :edit }
format.json { render json: #report.errors, status: :unprocessable_entity }
end
end
end
# DELETE /reports/1
# DELETE /reports/1.json
def destroy
#report.destroy
respond_to do |format|
format.html { redirect_to reports_url, notice: 'Report was successfully destroyed.' }
format.json { head :no_content }
end
end
# Adds CSV Uploader Method to Application
def import
Report.import(params[:file])
redirect_to reports_path, notice: "Report(s) Added Successfully"
end
private
# Use callbacks to share common setup or constraints between actions.
def set_report
#report = Report.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def report_params
params.require(:report).permit(:date, :site_id, :user_id, :type_of_report, :type_of_incident, :report)
end
end
my model looks like this:
class Report < ActiveRecord::Base
belongs_to :user
belongs_to :site
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
Report.create! row.to_hash
end
end
def self.to_csv
CSV.generate do |csv|
csv << column_names
all.each do |report|
csv << report.attributes.values_at(*column_names)
end
end
end
end
My Show Page Looks Like:
<p id="notice"><%= notice %></p>
<p>
<strong>Date:</strong>
<%= #report.date %>
</p>
<p>
<strong>Site:</strong>
<%= #report.site_id %>
</p>
<p>
<strong>Created By:</strong>
<%= #report.user_id %>
</p>
<p>
<strong>Type of report:</strong>
<%= #report.type_of_report %>
</p>
<p>
<strong>Type of incident:</strong>
<%= #report.type_of_incident %>
</p>
<p>
<strong>Report:</strong>
<%= #report.report %>
</p>
<%= link_to 'Edit', edit_report_path(#report) %> |
<%= link_to 'Back', reports_path %>
not too sure where I'm going wrong here.Any help would be greatly appreciated

Try changing the first parameter if your collection_select call from :site to :report:
<%= collection_select( :report, :site_id, Site.all, :id, :site_call_sign, {}, { :multiple => false } %>
My initial guess is that your form is passing up site_id as params[:site_id] instead of params[:report][:site_id], which is the format you'd need based on your strong parameters method in your controller:
def report_params
params.require(:report).permit(:date, :site_id, :user_id, :type_of_report, :type_of_incident, :report)
end
If it doesn't work, one thing you can do to help debug the issue is look at your rails console and see exactly the format that your form parameters are being sent from your view to the controller. Putting a couple puts statements in your action can help you better compare params versus report_params:
def create
puts "Params: #{params.inspect}"
puts "Report Params: #{report_params.inspect}"
#report = Report.new(report_params)
respond_to do |format|
if #report.save
format.html { redirect_to #report, notice: 'Report was successfully created.' }
format.json { render :show, status: :created, location: #report }
else
format.html { render :new }
format.json { render json: #report.errors, status: :unprocessable_entity }
end
end
end
Look in your server console for the output of those 2 puts statements. If you see site_id in params and not in report_params, you'll know your strong parameters method has filtered it out.

Related

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.

How to connect Devise User to ProfilesController Ruby on Rails 4

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.

Rails 4 nested forms link_to edit not working in loop

I have a nested routes/models/forms in rails. On my index page I am listing the todo_lists with the todo_items underneath. I want to be able to click on my todo list title and then it takes me to the edit page. I research polymorphic routes and nested routes.
UPDATE
This was my fix to stop it from creating the dummy todo list.
<% #current_todo_lists.each do |list| %>
<% if list.id %>
<div class="panel">
<p><strong><%= link_to list.title ,edit_todo_list_path(list)%></strong></p>
<% list.todo_items.each do |todo_item| %>
<p><%= todo_item.description %></p>
<% end %>
</div>
<% end %>
<% end %>
github link
Link_to rails nested form edit
polymorphic_path not generating correct path
I have done a lot quite a bit of research looking to cocoon, rails guides on polymorphic routes and several other stackoverflow links.
I have not been successful in making any of these work.
Here is the index page where all my todo_lists with todo_items are listed. It goes through a loop to list each todo list with the corresponding items created with it
Update:
I already tried <%= link_to list.title, edit_todo_list_path(list) %>and <%= link_to list.title, edit_todo_list_path(#list) %>.
The error message I get is :
ActionController::UrlGenerationError at /todo_lists
No route matches {:action=>"edit", :controller=>"todo_lists", :id=>nil} missing required keys: [:id]
This same configuration with #todo_list gives the same error.
Basically it can't find the Todo List with an id.
In the console does give me a result. So I am missing something.
>> t = TodoList.find(1)
=> #<TodoList id: 1, title: "First todo List with a modal", created_at: "2014-09-09 23:02:27", updated_at: "2014-09-09 23:02:27", user_id: 1>
>>
Update 2: This is where the error is happening in my todo list controller. It can't find without id.
def set_todo_list
#todo_list = TodoList.find(params[:id])
end
<% #todo_lists.each do |list| %>
<p><strong><%= link_to list.title, edit_polymorphic_path(#todo_list) %></strong></p>
<% list.todo_items.each do |todo_item| %>
<p><%= todo_item.description %></p>
<% end %>
<% end %>
So far <p><strong><%= link_to list.title, edit_polymorphic_path(#todo_list) % parameters have been #todo_list(s), # todo_lists(s), todo_items and so on.
Models:
class TodoList < ActiveRecord::Base
has_many :todo_items, dependent: :destroy
accepts_nested_attributes_for :todo_items, allow_destroy: true
validates_presence_of :title
end
class TodoItem < ActiveRecord::Base
belongs_to :todo_list
end
Controllers:
Class TodoListsController < ApplicationController
before_filter :authenticate_user!
before_filter except: [:index]
before_action :set_todo_list, only: [:show, :edit, :update, :destroy]
# GET /todo_lists
# GET /todo_lists.json
def index
##todo_lists = TodoList.all
#find current user todo lists/items
#todo_lists = current_user.todo_lists
#todo_items = current_user.todo_items
#create a new user todo list
#todo_list = current_user.todo_lists.new
# builder for todo list _form
3.times{ #todo_list.todo_items.build }
end
# GET /todo_lists/1
# GET /todo_lists/1.json
def show
end
# # GET /todo_lists/new
def new
#todo_list = current_user.todo_lists.new
3.times{ #todo_list.todo_items.build }
end
# GET /todo_lists/1/edit
def edit
##todo_list = TodoList.find(todo_list_params)
#todo_list = TodoList.find(params[:id])
end
# POST /todo_lists
# POST /todo_lists.json
def create
##todo_list = TodoList.new(todo_list_params)
#todo_list = current_user.todo_lists.new(todo_list_params)
respond_to do |format|
if #todo_list.save
format.html { redirect_to #todo_list, notice: 'Todo list was successfully created.' }
format.json { render :show, status: :created, location: #todo_list }
else
format.html { render :new }
format.json { render json: #todo_list.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /todo_lists/1
# PATCH/PUT /todo_lists/1.json
def update
#todo_list = TodoList.find(params[:id])
respond_to do |format|
if #todo_list.update(todo_list_params)
format.html { redirect_to #todo_list, notice: 'Todo list was successfully updated.' }
format.json { render :show, status: :ok, location: #todo_list }
else
format.html { render :edit }
format.json { render json: #todo_list.errors, status: :unprocessable_entity }
end
end
end
# DELETE /todo_lists/1
# DELETE /todo_lists/1.json
def destroy
##todo_list.TodoList.find(params[:id])
#todo_list.destroy
respond_to do |format|
format.html { redirect_to todo_lists_url, notice: 'Todo list was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def owns_todolist
if current_user != TodoList.find(params[:id]).user
redirect_to todo_lists_path, error: "You can't do that!"
end
end
# Use callbacks to share common setup or constraints between actions.
def set_todo_list
#todo_list = TodoList.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def todo_list_params
params.require(:todo_list).permit(:title, todo_items_attributes: [:description, :_destroy])
end
end
class TodoItemsController < ApplicationController
before_action :set_todo_item, only: [:show, :edit, :update, :destroy]
before_action :set_todo_list
# GET /todo_items
# GET /todo_items.json
def index
#todo_items = TodoItem.all
end
# GET /todo_items/1
# GET /todo_items/1.json
def show
#todo_item = TodoItem.find(params[:id])
end
# GET /todo_items/new
def new
#todo_item = #todo_list.todo_items.build
end
# GET /todo_items/1/edit
def edit
#todo_item = TodoItem.find(params[:id])
end
# POST /todo_items
# POST /todo_items.json
def create
#todo_item = #todo_list.todo_items.build(todo_item_params)
respond_to do |format|
if #todo_item.save
format.html { redirect_to [#todo_list,#todo_item], notice: 'Todo item was successfully created.' }
format.json { render :show, status: :created, location: #todo_item }
else
format.html { render :new }
format.json { render json: #todo_item.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /todo_items/1
# PATCH/PUT /todo_items/1.json
def update
#todo_item = TodoItem.find(params[:id])
respond_to do |format|
if #todo_item.update(todo_item_params)
format.html { redirect_to #todo_item, notice: 'Todo item was successfully updated.' }
format.json { render :show, status: :ok, location: #todo_item }
else
format.html { render :edit }
format.json { render json: #todo_item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /todo_items/1
# DELETE /todo_items/1.json
def destroy
#todo_item = TodoItem.find(params[:id])
#todo_item.destroy
respond_to do |format|
format.html { redirect_to todo_list_todo_items_url, notice: 'Todo item was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_todo_item
#todo_item = TodoItem.find(params[:id])
end
def set_todo_list
#todo_list = TodoList.find(params[:todo_list_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def todo_item_params
params.require(:todo_item).permit(:description, :text, :todo_list_id)
end
end
and finally the form. Right now it allows for adding a todo_list and a few todo_items just as practice. I plan on using some Ajax to allow for dynamic creation later on. And having a different form for editing.
<%= form_for(#todo_list) do |f| %>
<% if #todo_list.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#todo_list.errors.count, "error") %> prohibited this todo_list from being saved:</h2>
<ul>
<% #todo_list.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div>
<%= f.fields_for :todo_items do |builder| %>
<%= builder.label :description, "Items" %>
<%= builder.text_field :description %>
<%= builder.check_box '_destroy' %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I think the issue's actually a little trickier, because edit_todo_list_path(list) seems to throw the same error.
What's going on is that the #todo_lists variable (first an array of persisted lists) is altered when you run #todo_list = current_user.todo_lists.new. That command actually adds a new (unpersisted) list to the end of the #todo_lists array (seems like buggy behavior to me, but it's happened to me before), so that when your view is looping through them, the last one has no id, and a path cannot be created for it.
The solution is (I think) to make that variable after you've used the #todo_lists variable.
Take #todo_list out of the controller, and where you use it in the view, instead do current_user.todo_lists.build. That should instantiate a new list without changing the #todo_lists variable.
You are trying to create a link to a resource that has not been persisted yet:
#create a new user todo list
#todo_list = current_user.todo_lists.new
Since you never call #todo_list.save the record does not have a ID and cannot be routed to.
I think what you are trying to do is:
<% #todo_lists.each do |list| %>
<p><strong><%= link_to list.title, edit_polymorphic_path(id: list.to_param) #not #todo_list! %></strong></p>
<% list.todo_items.each do |todo_item| %>
<p><%= todo_item.description %></p>
<% end %>
<% end %>
And I would seriously consider renaming #todo_list -> #new_todo_list since it´s pretty confusing as is.
Update
"I can even click a button to open a modal which will create a new todo list all from the same page."
What you should do then is have the user create a new a resource by posting the form with an AJAX POST request to /todo_list and then update the page with the new list (and an edit link).
What you are doing now is creating a new todo_list which only exists in the servers memory before rails finishes processing the request.

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