为什么 simple_form 引发嵌套资源的 "No route matches [POST] "/tenants"" 错误

Why does simple_form raise an "No route matches [POST] "/tenants"" error with nested resources

我正在尝试制作一个用于创建新租户的简单表格,因为我知道当您创建租户时,必须同时创建一个 Devise User(with "role: "tenant")。但是当我提交表单时,它会引发 "Routing Error"(没有路由匹配 [POST]“/tenants”)。 (我正在使用 Devise 和 Pundit)

我有一个 属性 模型有很多租户模型

class Property < ApplicationRecord
  belongs_to :owner
  has_many :tenants, dependent: :destroy

  validates :address, presence: true
end

class Tenant < ApplicationRecord
  belongs_to :user
  belongs_to :property
  has_many :incidents, dependent: :destroy

  validates :first_name, presence: true
  validates :last_name, presence: true
  validates :email, presence: true, uniqueness: true
  validates :phone, presence: true
  validates :rental_price, presence: true
  validates :start_date, presence: true
  validates :rental_time, presence: true
end

路线如下:

Rails.application.routes.draw do
  root to: 'pages#home'
  devise_for :users

  resources :agencies do
    resources :owners, only: [:index, :new, :create]
  end
  resources :owners, only: [:show, :edit, :update, :destroy] do
    resources :properties, only: [:new, :create]
  end
  resources :properties, only: [:index, :show, :edit, :update, :destroy] do
    resources :tenants, only: [:new, :create]
  end
  resources :tenants, only: [:index, :show, :edit, :update, :destroy] do
    resources :incidents, only: [:new, :create]
  end
  resources :incidents, only: [:index, :show, :edit, :update, :destroy]
  resources :workers

租户管理员:

class TenantsController < ApplicationController
  before_action :set_tenant, only: [:show, :edit, :update, :destroy]

  def create
    @tenant = Tenant.new(tenant_params)
    @tenant.user = User.create(email: @tenant.email, password: random_password, role: "tenant")
    @tenant.property = Property.find(params[:property_id])
    if @tenant.save
      redirect_to :root
    else
      render :new
    end
    authorize(@tenant)
  end

  def new
    @tenant = Tenant.new
    @tenant.user = User.new
    @tenant.property = Property.find(params[:property_id])
    authorize(@tenant)
  end

  def show
    authorize(@tenant)
  end

  def index
    @tenants = policy_scope(Tenant).order(created_at: :desc)
  end

  def edit
    authorize(@tenant)
  end

  def update
    authorize(@tenant)
  end

  def destroy
    authorize(@tenant)
    @tenant.destroy
    redirect_back(fallback_location: root_path)
  end

  private

  def random_password
    (('0'..'9').to_a + ('A'..'Z').to_a + ('a'..'z').to_a).shuffle.first(6).join
  end

  def set_tenant
    @tenant = Tenant.find(params[:id])
  end

  def tenant_params
    params.require(:tenant).permit(:first_name, :last_name, :email, :phone, :rental_price, :start_date, :rental_time)
  end
end

new.html.erb

<%= simple_form_for [@property, @tenant] do |f| %>
  <%= f.input :first_name, label: false, placeholder: 'Prénom' %>
  <%= f.input :last_name, label: false, placeholder: 'Nom' %>
  <%= f.input :email, label: false, placeholder: 'Email' %>
  <%= f.input :phone, label: false, placeholder: 'Téléphone' %>
  <%= f.input :rental_price, label: false, placeholder: 'Montant du loyer en euros' %>
  <%= f.input :start_date, placeholder: 'Date de début de location' %>
  <%= f.input :rental_time, label: false, placeholder: 'Durée de location' %>

  <%= f.submit "  OK  " %>
<% end %>

和政策

class TenantPolicy < ApplicationPolicy
  class Scope < Scope
    def resolve
      scope.all
    end
  end

  def show?
    admin? || (agency? && user.agency.tenants.include?(record)) || (tenant? && user.tenant == record)
  end

  def index?
    admin? || (agency? && (record - user.agency.tenants).empty?)
  end

  def create?
    admin? || (agency? && user.agency.properties.include?(record.property))
  end

  def update?
    admin?
  end

  def destroy?
    admin? || (agency? && user.agency.tenants.include?(record))
  end
end

我真的很想知道为什么它在这里不起作用,因为我为 属性 模型(属于所有者)做了完全相同的事情并且它起作用了。 谢谢!

您的错误发生是因为您从路线中删除了 :create 操作:

resources :tenants, only: [:index, :show, :edit, :update, :destroy] 应该包括 :create

我发现问题所在:

我忘记在我的控制器方法中实例化@属性。