会社を選択すると、現場と品目の選択肢に、アソシエーションされているレコードをセットする
config/routes.rb
resources :companies do
get 'sites', on: :member
get 'waste_kinds', on: :member
end
app/controllers/companies_controller.rb
def sites
company = Company.find(params[:id])
sites = company.sites
respond_to do |format|
format.json { render json: sites }
end
end
def waste_kinds
company = Company.find(params[:id])
waste_kinds = company.waste_kinds
respond_to do |format|
format.json { render json: waste_kinds }
end
end
app/views/industrial_wastes/_form.html.erb
<div data-controller="company-select">
<div class="my-5">
<%= form.label :company_id, "会社" %><span class="text-red-500">*</span>
<%= form.collection_select(
:company_id,
Company.all,
:id,
:name,
{prompt: true},
class: "company-select shadow appearance-none border border-gray-200 rounded w-full py-2 px-3 mt-2 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
data: {
action: "change->company-select#onChange"
}
) %>
</div>
<div class="my-5">
<%= form.label :site_id, "現場" %><span class="text-red-500">*</span>
<%= form.collection_select(
:site_id,
[],
:id,
:name,
{prompt: "会社を先に選択してください"},
class: "shadow appearance-none border border-gray-200 rounded w-full py-2 px-3 mt-2 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
data: {
"company-select-target": "site"
}
) %>
</div>
<div class="my-5">
<%= form.label :waste_kind_id, "品目" %><span class="text-red-500">*</span>
<%= form.collection_select(
:waste_kind_id,
[],
:id,
:name,
{prompt: "会社を先に選択してください"},
class: "shadow appearance-none border border-gray-200 rounded w-full py-2 px-3 mt-2 text-gray-700 leading-tight focus:outline-none focus:shadow-outline",
data: {
"company-select-target": "wasteKind"
}
) %>
</div>
</div>
app/javascript/controllers/company_select_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["site", "wasteKind"]
onChange(event) {
this.updateSiteOptions(event.target.value);
this.updateWasteKindOptions(event.target.value);
}
updateSiteOptions(companyId) {
fetch(`/companies/${companyId}/sites.json`)
.then(response => response.json())
.then(data => {
let options = data.map(site => `<option value="${site.id}">${site.name}</option>`);
this.siteTarget.innerHTML = options.join("");
});
}
updateWasteKindOptions(companyId) {
fetch(`/companies/${companyId}/waste_kinds.json`)
.then(response => response.json())
.then(data => {
let options = data.map(wasteKind => `<option value="${wasteKind.id}">${wasteKind.name}</option>`);
this.wasteKindTarget.innerHTML = options.join("");
});
}
}