从模型回调中的表单复选框构建嵌套属性?

时间:2011-01-19 06:48:01

标签: ruby-on-rails forms callback data-modeling

我正在为一个小型分析实验室构建一个简单的样本跟踪器,我正在抨击我的问题。在结构上,数据库由用户,批次,样品,仪器和分析组成。请原谅凌乱或糟糕的代码,我是Rails和编程的新手。一般来说,我知道我在哪里邋and以及如何解决它,这只是我打破问题的问题。这是一些明确的删节代码:


class Batch  

  belongs_to :user
  has_many :samples
  has_many :submissions
  has_many :assays, :through => :submissions

  accepts_nested_attributes_for :samples
  accepts_nested_attributes_for :submissions

end

class Assay  

  belongs_to :instrument
  has_many :submissions
  has_many :batches, :through => :submissions

end

class Submission  

  belongs_to :batches
  belongs_to :assays

end

我创建了一个批量提交表单,它接受批处理信息,样本名称作为嵌套属性,我也试图接受提交作为嵌套属性。我的表单目前看起来像这样(请注意注释行):


= semantic_form_for @batch do |f|

  - @instruments.each do |instrument|
    %ol
      %li 
        = instrument.instrument_name
        %ol
          - instrument.assays.each do |assay|
            %li
              = assay.assay_name
              # Some magic check boxes that fix my problem. 

    = f.inputs :name => "Batch Info" do 
      = f.input :sampling_date, :required => false 
      = f.input :experiment_name, :required => false 
      = f.input :notes, :as => :text 

    = f.semantic_fields_for :samples do |sample_form|
      = sample_form.input :sample_name
    = f.buttons do 
      = f.commit_button :label => "Submit batch"

我想要的是每个检测的复选框,它将化验列表作为嵌套批次属性传递给提交表,神奇地确保每个批次与所选检测相关联。

我的问题是决定何时以及如何在控制器/模型中构建提交以及如何填充它们。看起来我应该制作一些包含assay_ids的参数,并使用某种模型回调(before_create或before_save)构建params[assay_ids].length个虚拟提交,我可以使用assay_id参数填充。不幸的是,我所有尝试构建一个方法都是徒劳的。

我已经看过所有可以找到的相关Railscast,阅读API条目,而且我已经研究了很长时间了。我能在大脑尖端感受到答案,而我迫切需要一个啊哈!时刻。感谢您提供的任何帮助!

1 个答案:

答案 0 :(得分:0)

注意:这种方法非常脆弱!我制定了一个解决方案,使批次成为真正的嵌套属性,我会尽快写出来。

所以经过一天的思考后,答案突然出现在我的脑海中(我发誓,我会使用Stack Overflow正式启动一个12小时的计时器,当时我会巧妙地弄明白我的错误)。我是这样做的:

基本上我只是尝试按照我的需要进行尽可能多的提交,所以我最终没有用空的数据库来填充我的数据库,但我也希望它们能够以动态的方式构建。因为我不想在我的视图中添加一些额外的逻辑,所以我将我的魔术复选框设置为check_box_tag "assay_ids[]", assay.id,以便将一个很好的参数与批处理参数分开。然后,在我create下的批处理控制器中,我构建了一个小帮手方法:

def build_submissions(params)
  @submitted_assays = params[:assay_ids]
  for submitted_assay in @submitted_assays do
    @batch.submissions.build(:assay_id => submitted_assay)
  end
end

这就像我需要的那样提交了很多提交内容。这个解决方案非常有效,但我欢迎任何有关如何以不同方式解决问题的建议。