Rails 5 has_and_belongs_to_many 表格
Rails 5 has_and_belongs_to_many form
我有一个带有客户端和站点模型的小应用程序。我想在显示页面的模态中创建一个新站点,但出现错误。
请在下面找到架构、控制器、模型和错误。
架构
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
我想从我的客户端创建一个站点#show page
<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">×</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
当您将模型数组作为 form_for 助手的参数传递时,rails 会尝试为该关系 (client_sites_path) 寻找路径。
您需要定义该路线。检查 rails 路由指南、嵌套资源部分和使用 url_for 助手的路径 https://guides.rubyonrails.org/routing.html#creating-paths-and-urls-from-objects
将站点资源嵌套在客户端资源中:
resources :clients do
resources :sites
end
并检查你的新路由,现在你应该在 rake routes
的输出上看到一条 client_sites 路由,并且 [@client, @site]
应该可以工作。
ActionView::Template::Error (undefined method `client_sites_path' for
Class:0x00007f9329282490>:0x00007f9329279890 Did you mean?
clients_path
edit_site_path):
错误表明没有名为 client_sites_path
的可用路径助手。确实如此,因为您没有以这种方式定义路线。根据您对 @arieljuod post 的评论,我了解到您想将 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 %>
创建一个 下拉菜单,您可以在其中 select 一个或多个客户 添加到将一起提交的站点使用 params
进入 sites#create
操作。
此外,您还应该通过将其添加到 site_params
方法来确保 白名单 client_ids: []
。通过这样做,Rails 在幕后使用这个 client_ids
值来为 clients_sites
table 生成条目。从而完成sites
到clients
的创建。
我有一个带有客户端和站点模型的小应用程序。我想在显示页面的模态中创建一个新站点,但出现错误。
请在下面找到架构、控制器、模型和错误。
架构
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
我想从我的客户端创建一个站点#show page
<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">×</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
当您将模型数组作为 form_for 助手的参数传递时,rails 会尝试为该关系 (client_sites_path) 寻找路径。
您需要定义该路线。检查 rails 路由指南、嵌套资源部分和使用 url_for 助手的路径 https://guides.rubyonrails.org/routing.html#creating-paths-and-urls-from-objects
将站点资源嵌套在客户端资源中:
resources :clients do
resources :sites
end
并检查你的新路由,现在你应该在 rake routes
的输出上看到一条 client_sites 路由,并且 [@client, @site]
应该可以工作。
ActionView::Template::Error (undefined method `client_sites_path' for Class:0x00007f9329282490>:0x00007f9329279890 Did you mean? clients_path edit_site_path):
错误表明没有名为 client_sites_path
的可用路径助手。确实如此,因为您没有以这种方式定义路线。根据您对 @arieljuod post 的评论,我了解到您想将 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 %>
创建一个 下拉菜单,您可以在其中 select 一个或多个客户 添加到将一起提交的站点使用 params
进入 sites#create
操作。
此外,您还应该通过将其添加到 site_params
方法来确保 白名单 client_ids: []
。通过这样做,Rails 在幕后使用这个 client_ids
值来为 clients_sites
table 生成条目。从而完成sites
到clients
的创建。