【问题标题】:Rails 5 Edit Form can't find path with nested model - routing errorRails 5 Edit Form 找不到嵌套模型的路径 - 路由错误
【发布时间】:2018-01-04 03:18:01
【问题描述】:

我有一个控制器,它处理一个表单的新操作和编辑操作,其中一个模型接受另一个表单的嵌套属性。 “新”动作效果很好。但是,当我去编辑表单并提交它时,它说:

Routing Error
No route matches [PATCH] "/admins/employees"

另外,当我在编辑页面上时,它不会在那里显示所有当前信息。只有“电子邮件”显示数据库中当前的内容。通常,编辑页面会显示数据库中当前与这些属性相关的内容,但此表单只是空白,电子邮件除外。不幸的是,谷歌搜索这个特定问题并没有找到任何相关或有用的信息。我认为 Rails 3 或其他一些东西很接近,但不适合我的问题。我正在使用 Rails 5.1。

我的代码如下:

员工控制器

class Admins::EmployeesController < UserActionsController
  def index
    @employees = User.where(:company => @current_company)
  end

  def edit
    @employee = User.find(params[:id])
  end

  def update
    @employee = User.find(params[:id])
    @employee.assign_attributes(employee_params)

    if @employee.save
      flash[:notice] = "Employee was updated."
      redirect_to root_path
    else
      flash.now[:alert] = "There was an error saving the information. Please try again."
      render :edit
    end
  end

  def show
    @employee = User.find(params[:id])
  end

  def new
    @employee = User.new
  end

  def create
    @employee = User.new(employee_params)
    @employee.company = @current_company

    if @employee.save
      redirect_to admins_employees_path
    else
      render :new
    end
  end

  private

  def employee_params
    params.require(:user).permit(:email, :password, :profile_attributes => [:firstName, :lastName, :title, :fullTime, :startDate])
  end
end

Edit.html.erb

<!--BODY-->
<%= render partial: 'form', locals: { employee: @employee, profile_attributes: :profile_attributes } %>
<!--BODY END-->

_form.html.erb

<%= form_for employee, url: admins_employees_path do |f| %>
  <div class="col-4 mb-3">
    <% if employee.errors.any? %>
      <div class="alert alert-danger">
        <h4><%= pluralize(employee.errors.count, "error") %>.</h4>
        <ul>
          <% employee.errors.full_messages.each do |msg| %>
            <li><%= msg %></li>
          <% end %>
        </ul>
      </div>
    <% end %>
    <div class="row">
      <div class="col p-0 mr-3">
        <div class="form-group">
          <%= f.label :email %>
          <%= f.text_field :email, class: 'form-control' %>
        </div>
        <div class="form-group">
          <%= f.label :password %>
          <%= f.text_field :password, class: 'form-control' %>
        </div>
        <%= f.fields_for profile_attributes do |user_f| %>
          <div class="form-group">
            <label>First Name</label>
            <%= user_f.text_field :firstName, :placeholder => 'First Name', class: 'form-control' %>
          </div>
          <div class="form-group">
            <label>Last Name</label>
            <%= user_f.text_field :lastName, :placeholder => 'Last Name', class: 'form-control' %>
          </div>
          <div class="form-group">
            Job <%= user_f.label :title %>
            <%= user_f.text_field :lastName, :placeholder => 'Title', class: 'form-control' %>
          </div>
          <div class="form-group">
            <label>Employment Start Date</label>
            <%= user_f.text_field :startDate, :placeholder => 'Start Date', class: 'form-control' %>
          </div>
        <% end %>
      </div>
      <div class="col-12 p-0">
        <%= f.submit "Submit", :class => 'btn btn-primary btn-block btn-lg' %>
      </div>
    </div>
  </div>
<% end %>

谢谢!

(编辑)路线

  Prefix Verb   URI Pattern                            Controller#Action
      employees_accounts GET    /employees/accounts(.:format)          employees/accounts#index
                         POST   /employees/accounts(.:format)          employees/accounts#create
   new_employees_account GET    /employees/accounts/new(.:format)      employees/accounts#new
  edit_employees_account GET    /employees/accounts/:id/edit(.:format) employees/accounts#edit
       employees_account GET    /employees/accounts/:id(.:format)      employees/accounts#show
                         PATCH  /employees/accounts/:id(.:format)      employees/accounts#update
                         PUT    /employees/accounts/:id(.:format)      employees/accounts#update
                         DELETE /employees/accounts/:id(.:format)      employees/accounts#destroy
         admins_accounts GET    /admins/accounts(.:format)             admins/accounts#index
                         POST   /admins/accounts(.:format)             admins/accounts#create
      new_admins_account GET    /admins/accounts/new(.:format)         admins/accounts#new
     edit_admins_account GET    /admins/accounts/:id/edit(.:format)    admins/accounts#edit
          admins_account GET    /admins/accounts/:id(.:format)         admins/accounts#show
                         PATCH  /admins/accounts/:id(.:format)         admins/accounts#update
                         PUT    /admins/accounts/:id(.:format)         admins/accounts#update
                         DELETE /admins/accounts/:id(.:format)         admins/accounts#destroy
        admins_employees GET    /admins/employees(.:format)            admins/employees#index
                         POST   /admins/employees(.:format)            admins/employees#create
     new_admins_employee GET    /admins/employees/new(.:format)        admins/employees#new
    edit_admins_employee GET    /admins/employees/:id/edit(.:format)   admins/employees#edit
         admins_employee GET    /admins/employees/:id(.:format)        admins/employees#show
                         PATCH  /admins/employees/:id(.:format)        admins/employees#update
                         PUT    /admins/employees/:id(.:format)        admins/employees#update
                         DELETE /admins/employees/:id(.:format)        admins/employees#destroy
           registrations GET    /registrations(.:format)               registrations#index
                         POST   /registrations(.:format)               registrations#create
        new_registration GET    /registrations/new(.:format)           registrations#new
       edit_registration GET    /registrations/:id/edit(.:format)      registrations#edit
            registration GET    /registrations/:id(.:format)           registrations#show
                         PATCH  /registrations/:id(.:format)           registrations#update
                         PUT    /registrations/:id(.:format)           registrations#update
                         DELETE /registrations/:id(.:format)           registrations#destroy
        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
                    root GET    /   

【问题讨论】:

  • 无需查看所有内容,&lt;%= form_for [:admins,employee] do |f| -%&gt; 让您无需添加网址即可执行相同操作。
  • 奇怪的是,当我把它改成那个时,因为我以前也试过,我得到这个错误:undefined method `admins_user_path' for #:0x007f6b751777c0> 你有没有意思是? admins_employees_path"
  • 请在问题中添加bundle exec rake routes
  • 已添加路线。谢谢
  • 您已与url: admins_employee_path(params[:id])核实

标签: ruby-on-rails forms ruby-on-rails-5 nested-routes


【解决方案1】:

为了您的信息,我想补充一点,rails 非常清晰,不需要用 form_for 告诉 url,原因是如果 form_form 中的对象是新的,它会在提交时自动点击创建操作,如果对象是已经存在,而不是在提交时触发更新操作。这就是partialdryform_for 的rails 概念的美妙之处,所以在这里

您有一个部分form 用于编辑和新操作

只需在此处更改一行:- 它不需要每次都告诉 url 以进行新的和更新的操作。

<%= form_for employee do |f| %>
 //your codes for form
<%end%>

也不需要传递nested_attribites局部变量,因为它会自动获取f对象

<%= render partial: 'form', locals: { employee: @employee } %>

但对于新操作,您需要 buildnested_attribute 对象

  def new
    @employee = User.new
    @employee.profile_attributes.build
  end

【讨论】:

  • 我很好奇你的回答。上面的答案对我有用,尽管它需要很少的、非常少的额外代码来区分更新和新的。但是,如果我按照您显示的方式编写代码,没有 url,我会收到此“错误:未定义方法 `users_path' for #:0x007f16f1cfbd68> 你的意思是?user_session_path”
  • @Coder 你在用 devise gem 吗?
  • 是的,我正在使用设计 gem。
  • @Coder 嗯,这就是为什么它与您的 devise 路线冲突的原因,因为设计路线也适用于 users,而您当前的路线也适用于 users
  • @Coder 有另一种方法可以做到这一点。但是,fom_for 的上述概念是正确的。另一种方法是为edit 操作单独设置一个部分,并手动为其提供url 以发送更新操作。就我而言,如果不提供带有 form_for 的 url,您的新操作也将不起作用,因为它的路由与设计路由冲突。
【解决方案2】:

您可以通过更改代码中的一点来消除所有这些错误。

edit.html.erb:

<%= form_for employee, url: admins_employee_path(params[:id]) do |f| %>
<%= render partial: 'form', locals: { employee: @employee, profile_attributes: :profile_attributes, f: f } %>
<% end %>

new.html.erb:

<%= form_for employee, url: admins_employees_path do |f| %>
<%= render partial: 'form', locals: { employee: @employee, profile_attributes: :profile_attributes, f: f } %>
<% end %>

并从formpartial 中删除表单行和结尾

【讨论】:

  • 我确实做了类似的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多