【发布时间】:2016-09-23 11:45:03
【问题描述】:
早安 StackOverflow,
我创建了一个管理命名空间,在命名空间内我有一个客户端资源,其中嵌套了一个站点资源,如下所示:
# routes.rb
namespace :admin do
resouurces :clients do
resources :sites
end
end
我在尝试从“站点”显示页面转到站点“编辑”页面时遇到以下错误:
ActionController::UrlGenerationError at /admin/clients/9A81622C/sites/88AA/edit
然后 BetterErrors 在错误消息下方给了我这个:
No route matches {:action=>"show", :client_id=>nil, :controller=>"admin/clients/sites", :id=>"88AA"} missing required keys: [:client_id]
admin_client_site 的 rake 路由输出如下:
admin_client_sites POST /admin/clients/:client_id/sites(.:format) admin/clients/sites#create
new_admin_client_site GET /admin/clients/:client_id/sites/new(.:format) admin/clients/sites#new
edit_admin_client_site GET /admin/clients/:client_id/sites/:id/edit(.:format) admin/clients/sites#edit
admin_client_site GET /admin/clients/:client_id/sites/:id(.:format) admin/clients/sites#show
PATCH /admin/clients/:client_id/sites/:id(.:format) admin/clients/sites#update
PUT /admin/clients/:client_id/sites/:id(.:format) admin/clients/sites#update
DELETE /admin/clients/:client_id/sites/:id(.:format) admin/clients/sites#destroy
“显示页面”上的编辑链接目前如下,这就是问题所在(或者我相信):
<%= link_to "Edit", edit_admin_client_site_path(@client, @site) %>
客户端的form_for,网站是:
<%= form_for [:admin, @client, @site], :url => admin_client_sites_url do |f| %>
我花了最后一天查看各种堆栈答案,但仍然无法解决这个问题,非常感谢这里的任何帮助,提前感谢,如果您需要更多文档,请告诉我!
编辑 #1 - 添加客户端和站点模型
Client.rb
class Client < ActiveRecord::Base
before_create :generate_client_ident
# Model Relations
has_many :sites, dependent: :destroy
# Model Validations
validates_uniqueness_of :client_ident
# Unique Admin Identifier
def generate_client_ident
begin
self.client_ident = SecureRandom.hex(4).upcase
other_client = Client.find_by(client_ident: self.client_ident)
end while other_client
end
# Vanity URL
def to_param
client_ident
end
end
Site.rb
class Site < ActiveRecord::Base
before_create :generate_site_ident
# Model Relations
belongs_to :client
# Model Validations
validates_uniqueness_of :site_ident
# Unique Admin Identifier
def generate_site_ident
begin
self.site_ident = SecureRandom.hex(2).upcase
other_site = Site.find_by(site_ident: self.site_ident)
end while other_site
end
# Vanity URL
def to_param
site_ident
end
end
编辑 #2 - 添加控制器
class Admin::Clients::SitesController < ApplicationController
before_action :authenticate_admin_admin!
before_action :set_site, only: [:show, :edit, :update, :destroy]
# GET /sites
# GET /sites.json
def index
@sites = Site.all
end
# GET /sites/1
# GET /sites/1.json
def show
@client = Client.find_by_client_ident(params[:id])
end
# GET /sites/new
def new
@client = Client.find_by_client_ident(params[:id])
@site = Site.new
end
# GET /sites/1/edit
def edit
@client = Client.find_by_client_ident(params[:id])
end
# POST /sites
# POST /sites.json
def create
@client = Client.find_by_client_ident(params[:id])
@site = Site.new(site_params)
@site.client = @client
respond_to do |format|
if @site.save
format.html { redirect_to admin_clients_url, notice: 'Site was successfully created.' }
format.json { render :show, status: :created, location: [:admin, @client] }
else
format.html { render :new }
format.json { render json: @site.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /sites/1
# PATCH/PUT /sites/1.json
def update
respond_to do |format|
if @site.update(site_params)
format.html { redirect_to [:admin, @client], notice: 'Site was successfully updated.' }
format.json { render :show, status: :ok, location: [:admin, @client] }
else
format.html { render :edit }
format.json { render json: @site.errors, status: :unprocessable_entity }
end
end
end
# DELETE /sites/1
# DELETE /sites/1.json
def destroy
@site.destroy
respond_to do |format|
format.html { redirect_to sites_url, notice: 'Site was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_site
@site = Site.find_by_site_ident(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def site_params
params.require(:site).permit(:client_id, :site_ident)
end
end
class Admin::ClientsController < ApplicationController
before_action :authenticate_admin_admin!
before_action :set_client, only: [:show, :edit, :update, :destroy]
# GET /clients
# GET /clients.json
def index
@clients = Client.all
end
# GET /clients/1
# GET /clients/1.json
def show
@client = Client.find_by_client_ident(params[:id])
@site = @client.sites
end
# GET /clients/new
def new
@client = Client.new
end
# GET /clients/1/edit
def edit
end
# POST /clients
# POST /clients.json
def create
@client = Client.new(client_params)
respond_to do |format|
if @client.save
format.html { redirect_to [:admin, @client], notice: 'Client was successfully created.' }
format.json { render :show, status: :created, location: @client }
else
format.html { render :new }
format.json { render json: @client.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /clients/1
# PATCH/PUT /clients/1.json
def update
respond_to do |format|
if @client.update(client_params)
format.html { redirect_to [:admin, @client], notice: 'Client was successfully updated.' }
format.json { render :show, status: :ok, location: @client }
else
format.html { render :edit }
format.json { render json: @client.errors, status: :unprocessable_entity }
end
end
end
# DELETE /clients/1
# DELETE /clients/1.json
def destroy
@client.destroy
respond_to do |format|
format.html { redirect_to [:admin, @client], notice: 'Client was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_client
@client = Client.find_by_client_ident(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def client_params
params.fetch(:client, {}).permit(:client_ident, :client_name, :street_number, :street_name, :unit_apt, :grid, :city,
:province, :postal_code, :office_tel, :office_ext, :cell_tel, :fax, :contact_email, :same_as_above,
:bill_to_client_name, :bill_to_street_number, :bill_to_street_name, :bill_to_grid, :bill_to_city,
:bill_to_province, :bill_to_postal_code)
end
end
编辑 #4 - 单击“站点显示页面”上的编辑链接时添加 Rails 服务器日志
Started GET "/admin/clients/9A81622C/sites/88AA" for ::1 at 2016-05-25 14:10:51 -0600
Processing by Admin::Clients::SitesController#show as HTML
Parameters: {"client_id"=>"9A81622C", "id"=>"88AA"}
Admin Load (0.4ms) SELECT "admins".* FROM "admins" WHERE "admins"."id" = $1 ORDER BY "admins"."id" ASC LIMIT 1 [["id", 1]]
Site Load (0.2ms) SELECT "sites".* FROM "sites" WHERE "sites"."site_ident" = $1 LIMIT 1 [["site_ident", "88AA"]]
Client Load (0.2ms) SELECT "clients".* FROM "clients" WHERE "clients"."id" = $1 LIMIT 1 [["id", 9]]
Rendered admin/clients/sites/show.html.erb within layouts/application (3.4ms)
Completed 500 Internal Server Error in 12ms (ActiveRecord: 0.8ms)
【问题讨论】:
-
显示 Admin::SitesController 中的内容。检查您是否在编辑操作中正确分配了@client 变量。错误说@client 是nil - 所以无法生成edit_admin_client_site_path 因为@site 必须与@client 相关并且不能与nil client 相关,显然。
-
我已经添加了控制器,看来我已经在需要的地方添加了变量。
-
我的建议是深入调试。在 show 操作中检查 @client 的值。检查链接轨生成的内容。检查请求是否进入编辑操作。
标签: ruby ruby-on-rails-4 model-view-controller nested-routes