2014-06-14 81 views
2

我的應用程序中有幾個多選項,在每次表單提交期間驗證總是失敗(獲取表單錯誤:類型不能爲空,語言不能爲空)(即使多 - 選擇選項被選中)。代碼:多選驗證總是失敗

型號/ 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

你是什麼意思「總是失敗」。請包含錯誤消息。 –

+0

我得到普通的表格錯誤:類型不能爲空,即使我選擇流派和語言,語言也不能爲空。 – Bounce

+1

可能是你的參數過濾問題。編輯或更新方法中的請求參數是什麼?我想'流派'應該是一個數組而不是單個值。所以'dvd_params'應該包含'流派:[]'而不是簡單的':流派'。 –

回答

1

表單的字段名稱應爲genre_idslanguage_ids,而不是genreslanguages

+0

好點。此外,我不得不改變dvd_params方法取決於帕維爾斯特拉霍夫評論。現在,該方法如下所示: params.require(:dvd).permit(:title,:description,:year,:length,genre_ids:[],language_ids:[])。 – Bounce