多选验证总是失败

时间:2014-06-14 08:07:14

标签: ruby-on-rails ruby-on-rails-4

我的应用程序中几乎没有选择,在每个表单提交期间验证总是失败(得到表单错误:类型不能为空,语言不能为空)(即使多选选择了选项)。代码:

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

任何想法有什么问题?

1 个答案:

答案 0 :(得分:1)

表单的字段名称应为genre_idslanguage_ids,而不是genreslanguages