我的应用程序中几乎没有选择,在每个表单提交期间验证总是失败(得到表单错误:类型不能为空,语言不能为空)(即使多选选择了选项)。代码:
模型/ dvd.rb
class Dvd < ActiveRecord::Base
has_and_belongs_to_many :genres
has_and_belongs_to_many :languages
has_many :rentals, dependent: :destroy
has_many :users, through: :rentals
validates :title, presence: true
validates :year, inclusion: {in: 1900..Time.now.year.to_i}, :presence => {:message => 'Year must be from 1900 till current year.'}
validates :length, inclusion: {in: 1..999}, :presence => {:message => 'DVD length must be in minutes in range 1..999.'}
validates :genres, presence: true
validates :languages, presence: true
end
模型/ language.rb
class Language < ActiveRecord::Base
has_and_belongs_to_many :dvds
validates :title, presence: true, uniqueness: { case_sensitive: false }
end
模型/ genre.rb
class Genre < ActiveRecord::Base
has_and_belongs_to_many :dvds
validates :title, presence: true, uniqueness: { case_sensitive: false }
end
dvds_controller.rb
class DvdsController < ApplicationController
before_action :set_dvd, only: [:show, :edit, :update, :destroy]
before_action :set_genres, :set_languages, only: [:new, :edit]
before_action :delete_genres, :delete_languages, only: [:update]
after_action :add_genres, :add_languages, only: [:create, :update]
# GET /dvds
# GET /dvds.json
def index
@dvds = Dvd.all
end
# GET /dvds/1
# GET /dvds/1.json
def show
end
# GET /dvds/new
def new
@dvd = Dvd.new
end
# GET /dvds/1/edit
def edit
end
# POST /dvds
# POST /dvds.json
def create
@dvd = Dvd.new(dvd_params)
respond_to do |format|
if @dvd.save
format.html { redirect_to @dvd, notice: 'Dvd was successfully created.' }
format.json { render :show, status: :created, location: @dvd }
else
format.html { render :new }
format.json { render json: @dvd.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /dvds/1
# PATCH/PUT /dvds/1.json
def update
respond_to do |format|
if @dvd.update(dvd_params)
format.html { redirect_to @dvd, notice: 'Dvd was successfully updated.' }
format.json { render :show, status: :ok, location: @dvd }
else
format.html { render :edit }
format.json { render json: @dvd.errors, status: :unprocessable_entity }
end
end
end
# DELETE /dvds/1
# DELETE /dvds/1.json
def destroy
@dvd.destroy
respond_to do |format|
format.html { redirect_to dvds_url, notice: 'Dvd was successfully deleted.' }
format.json { head :no_content }
end
end
private
def set_dvd
if params[:id]
@dvd = Dvd.find(params[:id])
else
@dvd = Dvd.find(params[:dvd][:id])
end
end
def dvd_params
params.require(:dvd).permit(:title, :description, :year, :genres, :languages, :length)
end
def add_languages
params[:dvd][:languages].each do |l|
if !l.empty?
@dvd.languages << Language.find(l)
end
end
end
def add_genres
params[:dvd][:genres].each do |g|
if !g.empty?
@dvd.genres << Genre.find(g)
end
end
end
def set_genres
@genres = Genre.all
end
def set_languages
@languages = Language.all
end
def delete_genres
# Delete all dvd genre relations
@dvd.genres.delete_all
end
def delete_languages
# Delete all dvd language relations
@dvd.languages.delete_all
end
end
的routes.rb
Rails.application.routes.draw do
resources :dvds do
resources :rentals
end
resources :rentals
resources :languages
resources :genres
resources :dvds
resources :users, :path => 'clients'
root to: "index#index"
end
形式
<div class="field">
<%= f.label :genres %><br>
<%= f.collection_select(:genres, Genre.all, :id, :title, {:selected => @dvd.genres.map {|dl| dl.id}, :include_blank => false}, {:multiple => true}) %>
</div>
<div class="field">
<%= f.label :languages %><br>
<%= f.select :languages, options_for_select(Language.all.map {|l| [l.title,l.id]}, @dvd.languages.map {|dl| dl.id}), {:include_blank=> false}, {:multiple => true} %>
</div>
任何想法有什么问题?
答案 0 :(得分:1)
表单的字段名称应为genre_ids
和language_ids
,而不是genres
和languages
。