没有路线匹配 [POST] “/downtowns/1/properties/new”

No route matches [POST] "/downtowns/1/properties/new"

我有一个与市区和物业具有一对多关系的应用程序。我一直遇到的麻烦是从市中心创建新的属性。我不断收到我用作此问题标题的错误。

我预感问题出在我的表单上(我使用的是简单表单 gem)。我可以转到我的 new 页面,填写表格,然后当我点击提交时,出现此错误。

我先展示我的表单文件。 (我在理解简单表单的文档时遇到了麻烦,这就是为什么我认为这就是问题所在)

= simple_form_for (@property), method: 'POST', url: new_downtown_property_path do |f|
  = f.input :name
  = f.input :last_remodel
  = f.input :original_construction_year

我的路线文件

resources :downtowns do
  resources :properties
end

我的市区控制器

def show
    @properties = Property.where(downtown: @downtown_id)
  end

  def new
    @downtown = Downtown.new
  end

  def create
    @downtown = Downtown.create(downtown_params)
    if @downtown.save
      redirect_to @downtown
    else
      render 'new'
    end
  end

  def downtown_params
    params.require(:downtown).permit(:name, :city)
  end

和我的属性控制器

  def new
    @property = Property.new
  end

  def create
    @downtown = property.find(id)
    @property = Property.create(params[:property_params])
    @property.downtown_id = @downtown.id

    if @property.save
      redirect_to @property
    else
      render 'new'
    end
  end

  def show
  end

您想 post 到 downtown_property_path 而不是 new_downtown_property_path

更多阅读这里https://guides.rubyonrails.org/routing.html

"/downtowns/1/properties/new" 是渲染模板以创建记录时的路由定义,它的动词是 GET。

在表格中,你需要的路径是URL那条路由来处理POST action,而action需要处理它我认为是"properties#create"如果你想使用 URL 正确的 URL 是 "downtown_properties_path"。您可以通过 运行 "rails routes" 命令获取详细信息。

= simple_form_for([@downtown, @property]) do |f|
  = f.input :name
  = f.input :last_remodel
  = f.input :original_construction_year

只需传递一个数组即可使用多态路由助手查找嵌套路由。这将正确使用 downtown_properties_path 作为动作。在 Rails 中,您始终通过发布到集合路径 (/downtowns/1/properties) 来创建资源。新路由只是呈现一个表单。您不需要指定方法,因为 Rails 会检测模型是否已持久化并相应地将方法设置为 POST 或 PATCH。

您也不应该在 Ruby:

中的方法名称和参数列表周围的括号之间添加 space
def add(a,b)
  a + b
end

add (1, 2) # syntax error
add (1), 2 # this is what actually happens 

Ruby 的行为与此处的示例 JS 非常不同,因为括号对于方法调用是可选的。

你的控制器也完全关闭了。嵌套的资源控制器应该看起来像。

class PropertiesController < ApplicationController
  before_action :set_downtown
  before_action :set_property, only: [:show, :edit, :update, :destroy]

  # GET /downtowns/1/properties/new
  def new
    @property = @downtown.properties.new
  end

  # POST /downtowns/1/properties
  def create
    @property = @downtown.properties.new(property_params)
    if @property.save
      redirect_to @property 
    else
      render :new
    end
  end

  # ...

  private

  def set_downtown
    @downtown = Downtown.includes(:properties).find(params[:downtown_id])
  end

  def set_propery
    @property = Property.find(params[:id])
  end

  def property_params
    params.require(:downtown)
          .permit(:name, :city)
  end

  # ...
end