问题
I have a rails 5 app using shallow resource nesting. The form_for has stopped working and I can't find why.
The App has multiple nested models that worked before changing to shallow routes on the recommendation from my previous question found here
My Schema is as follows:
db/schema.rb:
create_table "as1851_tests", force: :cascade do |t|
t.bigint "damper_id"
t.boolean "AS1851A", default: false, null: false
t.boolean "AS1851B", default: false, null: false
t.boolean "AS1851C", default: false, null: false
t.boolean "AS1851D", default: false, null: false
t.boolean "AS1851E", default: false, null: false
t.boolean "Pass", default: false, null: false
t.string "comment"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["damper_id"], name: "index_as1851_tests_on_damper_id"
end
create_table "dampers", force: :cascade do |t|
t.string "location"
t.string "number"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "site_id"
t.index ["site_id"], name: "index_dampers_on_site_id"
end
Models
app/models/damper.rb
class Damper < ApplicationRecord
belongs_to :site
has_many :as1851_tests
end
app/models/as1851_test.rb
class As1851Test < ApplicationRecord
belongs_to :damper
end
Controllers
app/controllers/as1851_tests_controller.rb
class As1851TestsController < ApplicationController
before_action :set_as1851_test, only: [:show, :edit, :update, :destroy]
# GET /as1851_tests
# GET /as1851_tests.json
def index
@as1851_tests = As1851Test.all
end
# GET /as1851_tests/1
# GET /as1851_tests/1.json
def show
end
# GET /as1851_tests/new
def new
@as1851_test = As1851Test.new
@as1851_test.damper = @damper
end
# GET /as1851_tests/1/edit
def edit
end
# POST /as1851_tests
# POST /as1851_tests.json
def create
@as1851_test = As1851Test.new(as1851_test_params)
@as1851_test.damper = @damper
respond_to do |format|
if @as1851_test.save
format.html { redirect_to @damper.site, notice: 'As1851 test was successfully created.' }
format.json { render :show, status: :created, location: @damper.site }
else
format.html { render :new }
format.json { render json: @damper.site, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /as1851_tests/1
# PATCH/PUT /as1851_tests/1.json
def update
respond_to do |format|
if @as1851_test.update(as1851_test_params)
format.html { redirect_to @as1851_test, notice: 'As1851 test was successfully updated.' }
format.json { render :show, status: :ok, location: @as1851_test }
else
format.html { render :edit }
format.json { render json: @as1851_test.errors, status: :unprocessable_entity }
end
end
end
# DELETE /as1851_tests/1
# DELETE /as1851_tests/1.json
def destroy
@as1851_test.destroy
respond_to do |format|
format.html { redirect_to as1851_tests_url, notice: 'As1851 test was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_as1851_test
@as1851_test = As1851Test.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def as1851_test_params
params.require(:as1851_test).permit(:damper_id, :AS1851A, :AS1851B, :AS1851C, :AS1851D, :AS1851E, :Pass, :comment)
end
end
app/controllers/dampers_controller.rb
class DampersController < ApplicationController
before_action :set_damper, except: [:new, :create]
# GET /dampers
# GET /dampers.json
def index
@dampers = Damper.all
end
# GET /dampers/1
# GET /dampers/1.json
def show
end
# GET /dampers/new
def new
@damper = Damper.new
end
# GET /dampers/1/edit
def edit
end
# POST /dampers
# POST /dampers.json
def create
@damper = Damper.new(damper_params)
@damper.site = @site
respond_to do |format|
if @damper.save
format.html { redirect_to @damper.site, notice: 'Damper was successfully created.' }
format.json { render :show, status: :created, location: @site }
else
format.html { render :new }
format.json { render json: @damper.site.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /dampers/1
# PATCH/PUT /dampers/1.json
def update
respond_to do |format|
if @damper.update(damper_params)
format.html { redirect_to @damper.site, notice: 'Damper was successfully updated.' }
format.json { render :show, status: :ok, location: @site }
else
format.html { render :edit }
format.json { render json: @damper.site.errors, status: :unprocessable_entity }
end
end
end
# DELETE /dampers/1
# DELETE /dampers/1.json
def destroy
@damper.destroy
respond_to do |format|
format.html { redirect_to @damper.site, notice: 'Damper was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_damper
@damper = Damper.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def damper_params
params.require(:damper).permit(:location, :number, :site_id, :client_id)
end
end
Routes
resources :clients, shallow: true do
resources :sites do
resources :dampers do
resources :as1851_tests
end
end
end
Form
app/views/as1851_tests/_form.html.erb <% form_for [@damper, @as1851_test] do |form| %>
<div class="form-group">
<%= form.label :damper_id %>
<%= form.text_field :damper_id, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.label :AS1851A %>
<%= form.check_box :AS1851A, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.label :AS1851B %>
<%= form.check_box :AS1851B, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.label :AS1851C %>
<%= form.check_box :AS1851C, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.label :AS1851D %>
<%= form.check_box :AS1851D, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.label :AS1851E %>
<%= form.check_box :AS1851E, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.label :Pass %>
<%= form.check_box :Pass, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.label :comment %>
<%= form.text_field :comment, class: 'form-control' %>
</div>
<div class="form-group">
<% if as1851_test.persisted? %>
<div class="float-right">
<%= link_to 'Destroy', as1851_test, method: :delete, class: "text-danger", data: { confirm: 'Are you sure?' } %>
</div>
<% end %>
<%= form.submit class: 'btn btn-primary' %>
</div>
<% end %>
The error that I get is
NoMethodError in As1851Tests#new
Showing /Users/jeremybray/RubymineProjects/ComplianceManagerv2/app/views/as1851_tests/_form.html.erb where line #1 raised:
undefined method `as1851_tests_path' for #<#<Class:0x00007fe0c7c820a8>:0x00007fe0c8325248>
Did you mean? as1851_test_path
as1851_test_url
Any help with this would be greatly appreciated as the whole shallow routes is new to me.
routes raked
Controller#Action
damper_as1851_tests GET /dampers/:damper_id/as1851_tests(.:format) as1851_tests#index
POST /dampers/:damper_id/as1851_tests(.:format) as1851_tests#create
new_damper_as1851_test GET /dampers/:damper_id/as1851_tests/new(.:format) as1851_tests#new
edit_as1851_test GET /as1851_tests/:id/edit(.:format) as1851_tests#edit
as1851_test GET /as1851_tests/:id(.:format) as1851_tests#show
PATCH /as1851_tests/:id(.:format) as1851_tests#update
PUT /as1851_tests/:id(.:format) as1851_tests#update
DELETE /as1851_tests/:id(.:format) as1851_tests#destroy
site_dampers GET /sites/:site_id/dampers(.:format) dampers#index
POST /sites/:site_id/dampers(.:format) dampers#create
new_site_damper GET /sites/:site_id/dampers/new(.:format) dampers#new
edit_damper GET /dampers/:id/edit(.:format) dampers#edit
damper GET /dampers/:id(.:format) dampers#show
PATCH /dampers/:id(.:format) dampers#update
PUT /dampers/:id(.:format) dampers#update
DELETE /dampers/:id(.:format) dampers#destroy
client_sites GET /clients/:client_id/sites(.:format) sites#index
POST /clients/:client_id/sites(.:format) sites#create
new_client_site GET /clients/:client_id/sites/new(.:format) sites#new
edit_site GET /sites/:id/edit(.:format) sites#edit
site GET /sites/:id(.:format) sites#show
PATCH /sites/:id(.:format) sites#update
PUT /sites/:id(.:format) sites#update
DELETE /sites/:id(.:format) sites#destroy
clients GET /clients(.:format) clients#index
POST /clients(.:format) clients#create
new_client GET /clients/new(.:format) clients#new
edit_client GET /clients/:id/edit(.:format) clients#edit
client GET /clients/:id(.:format) clients#show
PATCH /clients/:id(.:format) clients#update
PUT /clients/:id(.:format) clients#update
DELETE /clients/:id(.:format) clients#destroy
admin_users GET /admin/users(.:format) admin/users#index
POST /admin/users(.:format) admin/users#create
new_admin_user GET /admin/users/new(.:format) admin/users#new
edit_admin_user GET /admin/users/:id/edit(.:format) admin/users#edit
admin_user GET /admin/users/:id(.:format) admin/users#show
PATCH /admin/users/:id(.:format) admin/users#update
PUT /admin/users/:id(.:format) admin/users#update
DELETE /admin/users/:id(.:format) admin/users#destroy
admin_announcements GET /admin/announcements(.:format) admin/announcements#index
POST /admin/announcements(.:format) admin/announcements#create
new_admin_announcement GET /admin/announcements/new(.:format) admin/announcements#new
edit_admin_announcement GET /admin/announcements/:id/edit(.:format) admin/announcements#edit
admin_announcement GET /admin/announcements/:id(.:format) admin/announcements#show
PATCH /admin/announcements/:id(.:format) admin/announcements#update
PUT /admin/announcements/:id(.:format) admin/announcements#update
DELETE /admin/announcements/:id(.:format) admin/announcements#destroy
admin_notifications GET /admin/notifications(.:format) admin/notifications#index
POST /admin/notifications(.:format) admin/notifications#create
new_admin_notification GET /admin/notifications/new(.:format) admin/notifications#new
edit_admin_notification GET /admin/notifications/:id/edit(.:format) admin/notifications#edit
admin_notification GET /admin/notifications/:id(.:format) admin/notifications#show
PATCH /admin/notifications/:id(.:format) admin/notifications#update
PUT /admin/notifications/:id(.:format) admin/notifications#update
DELETE /admin/notifications/:id(.:format) admin/notifications#destroy
admin_services GET /admin/services(.:format) admin/services#index
POST /admin/services(.:format) admin/services#create
new_admin_service GET /admin/services/new(.:format) admin/services#new
edit_admin_service GET /admin/services/:id/edit(.:format) admin/services#edit
admin_service GET /admin/services/:id(.:format) admin/services#show
PATCH /admin/services/:id(.:format) admin/services#update
PUT /admin/services/:id(.:format) admin/services#update
DELETE /admin/services/:id(.:format) admin/services#destroy
admin_root GET /admin(.:format) admin/users#index
privacy GET /privacy(.:format) home#privacy
terms GET /terms(.:format) home#terms
notifications GET /notifications(.:format) notifications#index
announcements GET /announcements(.:format) announcements#index
sidekiq_web /sidekiq Sidekiq::Web
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
user_password PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
POST /users/password(.:format) devise/passwords#create
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
user_registration PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
POST /users(.:format) devise/registrations#create
back_user_masquerade_index GET /users/masquerade/back(.:format) devise/masquerades#back
user_masquerade GET /users/masquerade/:id(.:format) devise/masquerades#show
root GET / clients#index
rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
Update:
to me it looks like the routes are manipulated to singular by the shallow: true
回答1:
Well this had me stumped for a while but using the lead I found in this question I realised that the id is not set by the route or before_action anymore so I must stipulate it like so:
Controllers
app/controllers/as1851_tests_controller.rb
# GET /as1851_tests/new
def new
@damper = Damper.find(params[:damper_id])
@as1851_test = As1851Test.new
end
# GET /as1851_tests/1/edit
def edit
end
# POST /as1851_tests
# POST /as1851_tests.json
def create
@damper = Damper.find(params[:damper_id])
@as1851_test = As1851Test.new(as1851_test_params)
@as1851_test.damper = @damper
respond_to do |format|
if @as1851_test.save
format.html { redirect_to @damper.site, notice: 'As1851 test was successfully created.' }
format.json { render :show, status: :created, location: @damper.site }
else
format.html { render :new }
format.json { render json: @damper.site, status: :unprocessable_entity }
end
end
end
app/controllers/dampers_controller.rb
# GET /dampers/new
def new
@site = Site.find(params[:site_id])
@damper = Damper.new
end
# GET /dampers/1/edit
def edit
end
# POST /dampers
# POST /dampers.json
def create
@site = Site.find(params[:site_id])
@damper = Damper.new(damper_params)
@damper.site = @site
respond_to do |format|
if @damper.save
format.html { redirect_to @damper.site, notice: 'Damper was successfully created.' }
format.json { render :show, status: :created, location: @damper.site }
else
format.html { render :new }
format.json { render json: @damper.site.errors, status: :unprocessable_entity }
end
end
end
Pretty basic stuff really
来源:https://stackoverflow.com/questions/53028481/nomethoderror-in-as1851testsnew-with-shallow-routes