Rails 3 - 如何在外部类的 before_save 回调中基于 check_box_tag (不是模型的一部分)实现描述的更改情况

发布于 2024-12-27 04:31:29 字数 2720 浏览 1 评论 0原文

我有一个 Rails 3 应用程序,其中有多个注册(诊断、患者、实验室测试、服务、客户、用户、供应商)。最初,这些将通过播种数据库来填充。要求描述代码在以下任一情况下混合大小写(第一个单词大写): 1. 由应用程序指定(一些配置设置 - 尚未确定) 2.由数据输入用户指定

目前我有一个模型,视图和诊断控制器包含两个字段: 1. 代码(始终大写) 2.描述(基于 check_box_tag 值的第一个单词大写)

目前,我在模型中使用 before_save 回调来实现转换,但我无法让它仅在未选择 check_box_tag 时工作,即忽略 check_box_tag。

我尝试将 check_box_tag 更改为 check_box,向模型添加 attr_assessor (但不是 sqlite3 数据库,因为不需要存储它)。

这也行不通。

我该如何实现这个目标?如何覆盖使用内部应用程序配置文件中的复选框的选项,如果应用程序配置指定用户不可选择,该选项会导致复选框“不可用”或不可见?

模型 (diagnosis.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' 时,这仍然会被忽略。

如何让它发挥作用?

预先感谢一位有抱负的 Rails 开发人员。

I have an rails 3 application where there are multiple registrations (diagnosis, patient, laboratory test, service, client, user, supplier). Initially these will be populated by seeding the database. The requirement is for the description codes to be mixed case (capitalised first word) when either
1. specified by the application (some configuration setting - yet to be determined)
2. specified by data entry user

At present I have a model, view & controller for Diagnosis which contains two fields:
1. code (always to be capitalised)
2. description (First word capitalised based on check_box_tag value)

Presently I am using a before_save callback in the model to implement the conversion, but I cannot get it to only work when the check_box_tag is not selected i.e. its ignoring the check_box_tag.

I have tried changing the check_box_tag to a check_box adding an attr_assessor to the model (but not the sqlite3 db as it is not required to be stored).

This didn't work either.

How do I accomplish this? How do I override the option to use a checkbox from an internal application configuration file which results in either the checkbox being 'unavailable' or not visible if the application configuration specifies not user selectable?

Model (diagnosis.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

Callback in 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

Controller (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

View (_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 %>

When this runs currently the check_box_tag is ignored.

When adding in the model an attar_assessor :description_correctcase and changing the view to use f.check_box 'description_correctcase' this is still ignored.

How does one get this to work?

Thanks in advance from a rails aspiring developer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

惜醉颜 2025-01-03 04:31:29

在阅读并重新阅读了我的问题组成部分的各种 SO 解决方案之后,终于找到了问题的解决方案。我不确定它在轨道方面是否正确,但它有效。

如果您能为我提供更好的解决方案,我一定会从中学习。

这是我的解决方案。

模型(diagnosis.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。

View (_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 不会使用 @diagnosis.new 将其实例化为新记录的一部分
    有人可以确认一下吗?

  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

我非常想知道执行这一切的正确方法是什么,因为我觉得这不是很干燥或干净。

Finally got a solution to the problem, after reading and re-reading various SO solutions to component parts of my question. I'm not sure its correct in terms of rails, but it works.

If you can offer me a better solution I would certainly learn from this.

Here is my solution.

Model (diagnosis.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

This I referenced from the following SO solution - https://stackoverflow.com/a/6388691/1108010

Controller (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

I also changed the view to replace the check_box_tag with a check_box.

View (_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 %>

So despite getting this to work I'm not clear on are the following:

  1. When inspecting the attributes with "#{@diagnosis.attributes.inspect}".
    I assume that the reason the attr_accessor variable is not included in the New diagnosis output is that it is not part of the database table and therefore Active Reocrd does not instanciate it as part of the new record with @diagnosis.new
    Could someone be kind enough to confirm that.

  2. Why does the log have no value for logger.debug "code has value #{params[:code]}"? What causes the params[:code] to be null in the logger output?

Logfile contained the following entry:

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

I would dearly like to know what is the correct way to do all this, as I feel this is not very DRY or clean.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文