我是一名 Rails 新手,正在构建一个小应用程序来帮助我的工作。
我有客户端、站点和报价模型和控制器,并设置了视图。
我在报价模型上创建了一个表单,该表单从 collection_select 字段中的其他两个模型中提取数据。我发现关于 collection_select for rails 的文档非常糟糕。我想获取客户名称和站点名称,并在报价单上关联/显示名称。
我已经在表单中进行了设置,但它不会保存数据或显示它。
我真的很想了解 collection_select 的输入,因为我确信我的输入可能是错误的并导致了问题。
<%= f.collection_select :client, Client.all, :quote_client, :client_name , {:prompt => "Please select a client for the site"} %>
我做了一些研究并从@juanpastas 那里学到了这一点
我的表单看起来像这样引号/视图/_form.html
<%= form_for(quote) do |f| %>
<% if quote.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(quote.errors.count, "error") %> prohibited this quote from being saved:</h2><ul>
<% quote.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %><div class="field">
<%= f.label :client %>
<%= f.collection_select :client, Client.all, :quote_client, :client_name , {:prompt => "Please select a client for the site"} %>
</div><div class="field">
<%= f.label :site_name %>
<%= f.collection_select :site, Site.all, :quote_site, :site_name , {:prompt => "Please select a site for the quote"} %>
</div><div class="field">
<%= f.label :quote_contact %>
<%= f.text_field :quote_contact %>
</div><div class="field">
<%= f.label :quote_value %>
<%= f.text_field :quote_value %>
</div><div class="field">
<%= f.label :quote_description %>
<%= f.text_field :quote_description %>
</div><div class="actions">
<%= f.submit %>
</div>
<% end %>
编辑
答案/说明
报价只能有一个客户和一个站点。该网站也必须属于客户。
我有一个通过 Client.all 从客户端模型调用的客户端列表,以及通过 Site.all 调用的站点模型的站点列表。对于每个报价,我只需要一个客户的名称和一个站点的名称,但希望能够以级联方式进行选择。选择客户端,然后从可供客户端使用的站点中选择站点。
三个模型之间的关系是这样建立的:
class Quote < ApplicationRecord
belongs_to :site, optional: true
belongs_to :client, optional: true
has_and_belongs_to_many :assets
end
class Site < ApplicationRecord
has_attached_file :site_image, styles: { small: "64x64", med: "100x100", large: "200x200" }
do_not_validate_attachment_file_type :site_image
belongs_to :client , optional: true
has_and_belongs_to_many :assets
has_and_belongs_to_many :quotes
end
class Client < ApplicationRecord
has_and_belongs_to_many :sites
has_and_belongs_to_many :assets
has_and_belongs_to_many :quotes
end
控制器
class QuotesController < ApplicationController
before_action :set_quote, only: [:show, :edit, :update, :destroy]
# GET /quotes
# GET /quotes.json
def index
@quotes = Quote.all
end
# GET /quotes/1
# GET /quotes/1.json
def show
end
# GET /quotes/new
def new
@quote = Quote.new
end
# GET /quotes/1/edit
def edit
end
# POST /quotes
# POST /quotes.json
def create
@quote = Quote.new(quote_params)
respond_to do |format|
if @quote.save
format.html { redirect_to @quote, notice: 'Quote was successfully created.' }
format.json { render :show, status: :created, location: @quote }
else
format.html { render :new }
format.json { render json: @quote.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /quotes/1
# PATCH/PUT /quotes/1.json
def update
respond_to do |format|
if @quote.update(quote_params)
format.html { redirect_to @quote, notice: 'Quote was successfully updated.' }
format.json { render :show, status: :ok, location: @quote }
else
format.html { render :edit }
format.json { render json: @quote.errors, status: :unprocessable_entity }
end
end
end
# DELETE /quotes/1
# DELETE /quotes/1.json
def destroy
@quote.destroy
respond_to do |format|
format.html { redirect_to quotes_url, notice: 'Quote was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_quote
@quote = Quote.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def quote_params
params.require(:quote).permit(:quote_client, :quote_site, :client_name, :site_name, :quote_contact, :quote_value, :quote_description)
end
end
class SitesController < ApplicationController
before_action :set_site, only: [:show, :edit, :update, :destroy]
# GET /sites
# GET /sites.json
def index
@sites = Site.all
@clients = Client.all
end
# GET /sites/1
# GET /sites/1.json
def show
@sites = Site.all
@clients = Client.all
end
# GET /sites/new
def new
@site = Site.new
end
# GET /sites/1/edit
def edit
end
# POST /sites
# POST /sites.json
def create
@site = Site.new(site_params)
respond_to do |format|
if @site.save
format.html { redirect_to @site, notice: 'Site was successfully created.' }
format.json { render :show, status: :created, location: @site }
else
format.html { render :new }
format.json { render json: @site.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /sites/1
# PATCH/PUT /sites/1.json
def update
respond_to do |format|
if @site.update(site_params)
format.html { redirect_to @site, notice: 'Site was successfully updated.' }
format.json { render :show, status: :ok, location: @site }
else
format.html { render :edit }
format.json { render json: @site.errors, status: :unprocessable_entity }
end
end
end
# DELETE /sites/1
# DELETE /sites/1.json
def destroy
@site.destroy
respond_to do |format|
format.html { redirect_to sites_url, notice: 'Site was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_site
@site = Site.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def site_params
params.require(:site).permit(:site_client, :client_name, :site_name, :site_image, :site_address, :site_contact)
end
end
class ClientsController < ApplicationController
before_action :set_client, only: [:show, :edit, :update, :destroy]
# GET /clients
# GET /clients.json
def index
@clients = Client.all
@sites = Site.all
end
# GET /clients/1
# GET /clients/1.json
def show
@clients = Client.all
@sites = Site.all
end
# GET /clients/new
def new
@client = Client.new
end
# GET /clients/1/edit
def edit
end
# POST /clients
# POST /clients.json
def create
@client = Client.new(client_params)
respond_to do |format|
if @client.save
format.html { redirect_to @client, notice: 'Client was successfully created.' }
format.json { render :show, status: :created, location: @client }
else
format.html { render :new }
format.json { render json: @client.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /clients/1
# PATCH/PUT /clients/1.json
def update
respond_to do |format|
if @client.update(client_params)
format.html { redirect_to @client, notice: 'Client was successfully updated.' }
format.json { render :show, status: :ok, location: @client }
else
format.html { render :edit }
format.json { render json: @client.errors, status: :unprocessable_entity }
end
end
end
# DELETE /clients/1
# DELETE /clients/1.json
def destroy
@client.destroy
respond_to do |format|
format.html { redirect_to clients_url, notice: 'Client was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_client
@client = Client.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def client_params
params.require(:client).permit(:client_name, :client_address, :client_phone, :client_email, :client_website)
end
end
加法
您可能会注意到我试图扩展,以便在站点和站点中调用客户端,并在报价中调用客户端。