Rails 4.2: проверки на стороне клиента для ассоциаций

У меня есть сложная форма с ассоциациями, которые я хотел бы просматривать в реальном времени ошибки валидации в режиме реального времени. Я наткнулся на RailsCasts эпизод проверки на стороне клиента и решил воспользоваться этим подходом и установил гем.

gem 'client_side_validations', 
      github: "DavyJonesLocker/client_side_validations", 
      branch: "4-2-stable"

Как того требует самоцвет, я разместил validate: true в верхней части формы помощник и увидел, что он работает только на полях атрибутов, а не на связанных объектах.

Например, когда поле name пусто, в нем отображается сообщение об ошибке can't be blank, Когда пользователь не выбрал program Я хотел бы сообщить пользователю Need a program! но это не так. В настоящее время он просто выбрасывает flash[:error] сообщение, которое я заявил в контроллере, что "There was a problem launching your Campaign." без встроенного сообщения, специфичного для program выберите поле.

Ошибка подтверждения отображения имени, но программа - нет

Вот установка..

просмотры / кампания /_forms.html.erb

<%= form_for @campaign, url: {action: "create"}, validate: true do |f| %>

                <%= f.label :campaign_name, "Campaign Name", class: "right-label" %>
                <%= f.text_field :name %>

                <%= f.label :comments %>
                <%= f.text_area :comment %>

                <%= f.label :program %> 
                <%= f.select :program_id, 
                        Program.all.collect { |p| [ p.name, p.id ] }, { include_blank: true }, validate: { presence: true } %>

                <%= f.label :data_file, "Data File (.zip)", class: "right-label" %>

                <%= select_tag :uploadzip_id, 
                                options_from_collection_for_select(
                                Uploadzip.all, :id, :file_name
                                ), { include_blank: "Include a Zip File" } %>

                <%= f.label :additional_files %>

                <ul><%= f.collection_check_boxes :uploadpdf_ids, Uploadpdf.last(5).reverse, :id,
                             :file_name, { mulitple: true } do |b| %>
                             <li><%= b.label do %>
                                    <%= b.check_box + truncate(File.basename(b.text,'.*'), length: 45) %>
                                 <% end %>
                </ul><% end %>

<%= render 'target', :f => f %> 
<%= f.submit "Confirm & Execute", id: "campaign-create-button" %>

<% end %>

просмотры / кампания /_target.html.erb

            <%= f.label :plan, "Pick a Plan", class: "right-label" %>

            <%= f.select :plan_id,
                    Plan.all.collect { |p| 
                        [ p.name, p.id ] 
                        }, { include_blank: true } %>

                <%= f.label :channels, "Distribution Channel", class: "right-label" %>

            <ul class="channels-list">
                <% ["Folder", "Fax", "Email"].each do |channel| %>

                <li><%= check_box_tag "campaign[channels][]", channel,
                        @campaign.channels.include?(channel), 
                        id: "campaign_channels_#{channel}"  %> <%= channel %></li>
                <% end %>
            </ul>

приложение / модели / campaign.rb

class Campaign < ActiveRecord::Base
    belongs_to :program
    belongs_to :plan

    has_many :uploadables, dependent: :destroy
    has_many :uploadpdfs, through: :uploadables
    has_one :uploadzip, dependent: :nullify

    validates :name, presence: true,
                    uniqueness: true
    validates :program, presence: { message: "Need a program!"}
    validates :uploadzip, presence: true
    validates :uploadpdf_ids, presence: true

    serialize :channels, Array

end

приложение / контроллеры /campaigns_controller.rb

class CampaignsController < ApplicationController
      def index
        @campaigns = Campaign.all.order("created_at DESC")
      end

      def new
        @campaign = Campaign.new
      end

      def create
        @campaign = Campaign.new(campaign_params)


        if @campaign.save

            zip = Uploadzip.find(params[:uploadzip_id])
            zip.campaign = @campaign
            zip.save

            flash[:success] = "Campaign Successfully Launched!"
            redirect_to @campaign
        else
            flash[:error] = "There was a problem launching your Campaign."
            redirect_to new_campaign_path
        end
      end

      def show
        @campaign = Campaign.includes(:program, :uploadzip, :plan, :uploadpdfs).find(params[:id])
      end

  private

      def campaign_params
        params.require(:campaign).permit(:name, :comment, :plan_id, :program_id, :campaign_id, uploadpdf_ids: [], channels: [])
      end
end

Я также следовал этому руководству, в котором содержался код, помогающий отображать ошибки проверки ассоциаций в представлении.

конфиг / Инициализаторы /errors_for_associations.rb

module ActionView::Helpers::ActiveModelInstanceTag
  def error_message_with_associations
    if @method_name.end_with?('_ids')
      # Check for a has_(and_belongs_to_)many association (these always use the _ids postfix field).
      association = object.class.reflect_on_association(@method_name.chomp('_ids').pluralize.to_sym)
    else
      # Check for a belongs_to association with method_name matching the foreign key column
      association = object.class.reflect_on_all_associations.find do |a|
        a.macro == :belongs_to && a.foreign_key == @method_name
      end
    end
    if association.present?
      object.errors[association.name] + error_message_without_associations
    else
      error_message_without_associations
    end
  end
  alias_method_chain :error_message, :associations
end

0 ответов

Другие вопросы по тегам