Rails 5 has_and_belongs_to_many形式

时间:2018-10-18 23:34:27

标签: ruby-on-rails ruby-on-rails-5 has-and-belongs-to-many

我有一个带有客户端和站点模型的小应用程序。我想从显示页面以模态创建一个新站点,但是却出现错误。

请在下面找到架构,控制器,模型和错误。

模式

create_table "clients", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "clients_sites", id: false, force: :cascade do |t|
    t.bigint "client_id", null: false
    t.bigint "site_id", null: false
  end

create_table "sites", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

我想从我的客户#显示页面创建一个网站

<div class="page-header">
  <%= link_to clients_path, class: 'btn btn-default' do %>
    <span class="glyphicon glyphicon-list-alt"></span>
    All Clients
  <% end %>
  <%= link_to edit_client_path(@client), class: 'btn btn-primary' do %>
    <span class="glyphicon glyphicon-pencil"></span>
    Edit
  <% end %>
  <h1>Show client</h1>
</div>

<dl class="dl-horizontal">
  <dt>Name:</dt>
  <dd><%= @client.name %></dd>

</dl>


<div class="row">
  <div class="col-sm-6">
    <h1>Sites</h1>
  </div>

  <div class="col-sm-6 text-right">
    <!-- Button trigger modal -->
    <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
      Add New Site
    </button>

    <!-- Modal -->
    <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
      <div class="modal-dialog" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body">
            <%= form_for [@client, @site] do |f| %>
              <%= form.label :name %>
              <%= form.text_field :name, class: 'form-control' %>
              <%= form.submit class: 'btn btn-primary' %>
            <% end %>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
            <button type="button" class="btn btn-primary">Save changes</button>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

<div class="table-responsive">
  <table class="table table-striped table-bordered table-hover">
    <thead>
    <tr>

      <th>Name</th>



    </tr>
    </thead>

    <tbody>
    <% @client.sites.each do |site| %>
      <%= content_tag :tr, id: dom_id(site), class: dom_class(site) do %>

        <td><%= link_to site.name, site %></td>




      <% end %>
    <% end %>
    </tbody>
  </table>
</div>

客户端控制器

  def show
    @client = Client.find(params[:id])
    @site = Site.new
  end

app / models / client.rb

class Client < ApplicationRecord
  has_and_belongs_to_many :sites
end

app / models / site.rb

class Site < ApplicationRecord
  has_and_belongs_to_many :clients
end

当我点击页面时,出现以下错误

ActionView::Template::Error (undefined method `client_sites_path' for #<#<Class:0x00007f9329282490>:0x00007f9329279890>
Did you mean?  clients_path
               edit_site_path):
    39:             </button>
    40:           </div>
    41:           <div class="modal-body">
    42:             <%= form_for [@client, @site] do |f| %>
    43:               <%= form.label :name %>
    44:               <%= form.text_field :name, class: 'form-control' %>
    45:               <%= form.submit class: 'btn btn-primary' %>

app/views/clients/show.html.erb:42:in `_app_views_clients_show_html_erb___1421137287308647677_70135013712680'

编辑

路线

 sites GET    /sites(.:format)                                                                         sites#index
                           POST   /sites(.:format)                                                                         sites#create
                  new_site GET    /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

Rails.application.routes.draw do
  resources :sites
  resources :clients

2 个答案:

答案 0 :(得分:2)

  

ActionView :: Template :: Error(未定义的方法“ client_sites_path”用于   类别:0x00007f9329282490>:0x00007f9329279890是什么意思?   clients_path                  edit_site_path):

该错误表明没有名为client_sites_path的可用路径助手。确实如此,因为您没有以这种方式定义路线。根据您对 @arieljuod 帖子的评论,我了解到您想将sites保存到clients。以下代码将帮助您实现所需的目标

<%= form_for @site do |f| %>
  <%= form.label :name %>
  <%= form.text_field :name, class: 'form-control' %>
  <%= form.select :client_ids, options_from_collection_for_select(Client.all, :id, :name), :prompt => "Select Clients", :multiple => true %>
  <%= form.submit class: 'btn btn-primary' %>
<% end %>

这段代码片段

<%= form.select :client_ids, options_from_collection_for_select(Client.all, :id, :name), :prompt => "Select Clients", :multiple => true %>

创建一个下拉列表,您可以在其中选择一个或多个客户以添加到将与params一起提交到{ {1}}操作。

此外,您还应该通过将其添加到sites#create方法中来确保白名单 client_ids: []。通过这样做,Rails可以使用此site_params值来生成client_ids表的条目。这样就完成了clients_sitessites的创建。

答案 1 :(得分:0)

当您将模型数组作为form_for辅助函数的参数传递时,rails会尝试查找该关系的路径(client_sites_path)。

您需要定义该路线。使用url_for helpers https://guides.rubyonrails.org/routing.html#creating-paths-and-urls-from-objects

查看Rails路由指南,嵌套资源部分和路径。

将站点资源嵌套到客户端资源中

resources :clients do
  resources :sites
end

并检查您的新路由,现在您应该在rake routes的输出上看到一个client_sites路由,并且[@client, @site]应该可以正常工作。