Rails 3 - как реализовать изменение регистра описаний на основе check_box_tag (не является частью модели) в обратном вызове before_save во внешнем классе - PullRequest
0 голосов
/ 15 января 2012

У меня есть приложение на рельсы 3, где есть несколько регистраций (диагноз, пациент, лабораторный тест, сервис, клиент, пользователь, поставщик).Первоначально они будут заполнены путем заполнения базы данных.Требуется, чтобы коды описания были в смешанном регистре (заглавные слова), если либо 1. указано приложением (некоторые настройки конфигурации - еще не определены) 2. указано пользователем ввода данных

В настоящее время Iиметь модель, представление и контроллер для диагностики, который содержит два поля: 1. код (всегда с заглавной буквы) 2. описание (первое слово с заглавной буквы на основе значения check_box_tag)

В настоящее время я использую обратный вызов before_save вмодель для реализации преобразования, но я не могу заставить его работать, только когда check_box_tag не выбран, то есть игнорируется check_box_tag.

Я попытался изменить check_box_tag на check_box, добавив attr_assessor в модель (но неsqlite3 db, поскольку его не нужно хранить).

Это тоже не сработало.

Как мне это сделать?Как переопределить опцию использования флажка из внутреннего файла конфигурации приложения, что приводит к тому, что флажок будет «недоступен» или не будет отображаться, если в конфигурации приложения указано, что пользователь не может быть выбран?

Модель (Diagnostics.rb)

require 'DescriptionHelper'

class Diagnosis < ActiveRecord::Base
  attr_accessible :code, description

  string_correct_case = DescriptionHelper.new([:code, :description])

  validates :code, :presence => true, :length => { :minimum => 4, :maximum => 4 }
  validates :description, :presence => true

  before_save string_correct_case

end

Обратный вызов в DescriptionHelper.rb

class DescriptionHelper
  def initialize(attribute)
    @attrs_to_manage = attribute
  end

  def before_save(record)
    @attrs_to_manage.each do |attribute|
      record.send("#{attribute}=", capitaliseWords(record.send("#{attribute}")))
    end
  end

  private
    def capitaliseWords(value)
      value = value.mb_chars.downcase.to_s.gsub(/\b\w/) { |first| first.upcase }
    end
  end

Контроллер (Diagnoses_controller.rb)

class DiagnosesController < ApplicationController

  def new
    @diagnosis = Diagnosis.new
  end

  def create
    @diagnosis = Diagnosis.new(params[:diagnosis])

    if @diagnosis.save
      flash[:notice] = "Diagnosis created with params [#{@diagnosis.attributes.inspect}" #for debugging, once fixed will be just 'Diagnosis created.'
      redirect_to @diagnosis
    else
      flash[:alert] = "Diagnosis not created."
      render :action => "new"
    end
  end

  .. other controller actions - edit, show, destroy

end

Просмотр (_form.html.erb)

<%= form_for(@daignosis) do |f| %>
  <div class="field">
    <%= f.label :code %>
    <%= f.text_field :code %>
  </div>
  <div class="field">
    <%= f.label :description %>
    <%= f.text_field :description %>
  </div>
  <div class="field">
    <%= check_box_tag("diagnosis_desc_dont_convert", 1, false) %><%= f.label "Leave as entered" %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Когда это выполняется в настоящий момент, check_box_tag игнорируется.

При добавлении в модель attar_assessor: description_correctcase и изменении представления для использования f.check_box 'description_correctcase' это все еще игнорируется.

Как заставить это работать?

Заранее спасибо начинающему разработчику рельсов.

1 Ответ

0 голосов
/ 05 марта 2012

Наконец-то получил решение проблемы, прочитав и перечитав различные SO-решения для составных частей моего вопроса.Я не уверен, что это правильно с точки зрения рельсов, но это работает.

Если вы можете предложить мне лучшее решение, я, безусловно, извлеку урок из этого.

Вот мое решение.

Модель (одиагностика.rb)

require 'DescriptionHelper'

class Diagnosis < ActiveRecord::Base
  attr_accessor   :do_not_correctcase
  attr_accessible :code, :description, :do_not_correctcase

  before_save DescriptionHelper.new([:code, :description]), :if => 
                         lambda { |d| d.do_not_correctcase.to_s == '0' }

  validates :code, :presence => true, :length => { :minimum => 4, :maximum => 4 }
  validates :description, :presence => true

end

На это я ссылаюсь из следующего решения SO - https://stackoverflow.com/a/6388691/1108010

Контроллер (Diagnoses_controller.rb)

class DiagnosesController < ApplicationController

  def new
    @diagnosis = Diagnosis.new
  end

  def create
    @diagnosis = Diagnosis.new(params[:diagnosis])
    @diagnosis.do_not_correctcase = params[:diagnosis][:do_not_correctcase]

    logger.debug "New diagnoses: #{@diagnosis.attributes.inspect}"
    logger.debug "Diagnosis should be valid: #{@diagnosis.valid?}"
    logger.debug "code has value #{params[:code]}"


    if @diagnosis.save
      flash[:notice] = "Diagnosis created with params [#{@diagnosis.attributes.inspect}" #for debugging
      redirect_to @diagnosis
    else
      flash[:alert] = "Diagnosis not created."
      render :action => "new"
    end
  end

  .. other controller actions - edit, show, destroy

end

Я также изменил представление, чтобы заменить check_box_tag на check_box.

Представление (_form.html.erb)

<%= form_for(@daignosis) do |f| %>
  <div class="field">
    <%= f.label :code %>
    <%= f.text_field :code %>
  </div>
  <div class="field">
    <%= f.label :description %>
    <%= f.text_field :description %>
  </div>
  <div class="field">
    <%= f.check_box 'do_not_correctcase' %><%= f.label "Leave as entered" %><br />
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Так что, несмотря на то, что это работает, мне не ясноследующие:

  1. При проверке атрибутов с помощью "#{@diagnosis.attributes.inspect}".Я предполагаю, что причина, по которой переменная attr_accessor не включена в вывод новой диагностики, заключается в том, что она не является частью таблицы базы данных, и, следовательно, Active Reocrd не создает ее как часть новой записи с параметром @одиагностика.чтобы подтвердить это.

  2. Почему в журнале нет значения для logger.debug "code has value #{params[:code]}"?Что заставляет params[:code] быть нулевым в выходных данных регистратора?

В лог-файле содержится следующая запись:

Started POST "/diagnoses" for 127.0.0.1 at 2012-03-05 09:36:38 +0000
  Processing by DiagnosesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"RW/mzkhavGeaIW0hVLn0ortTnbCDlrX+FfzH4neLLsA=", "diagnosis"=>{"code"=>"tt02", "description"=>"description for tt02", "do_not_correctcase"=>"1"}, "commit"=>"Create Diagnosis"}
New diagnosis: {"code"=>"tt02", "created_at"=>nil, "description"=>"description for tt02", "updated_at"=>nil}
Diagnosis should be valid: true
code has value

Я бы очень хотел узнать, что этоправильный способ сделать все это, поскольку я чувствую, что это не очень СУХОЙ или чистый.

...