Rails字段_for、可选字段和验证



我有一个事件模型has many :bands, through: :event_bands。CCD_ 2模型为CCD_。

在事件创建时,用户从如下多选中选择波段:

<p>
    <%= f.label t(:band_playing) %>
    <%= f.collection_select :band_ids, Band.order(:name), :id, :name, {}, {multiple: true} %>
</p>

但是,如果用户找不到合适的band,我希望他们能够在我的事件模型中使用accepts_nested_attributes_for :bands在具有关联的同一表单上创建band。

所以,我把它添加到我的表单中,我用一些jQuery:隐藏/显示它

    <div id="new_bands">
        <p>
            <%= f.fields_for :bands do |ff| %>
                <%= ff.label "New Band Name" %>
              <%= ff.text_field :name, class: "form-control half" %>
            <% end %>
      </p>
    </div>

然而,为了使fields_for正常工作,我需要像这样建立关联我的事件控制器:

def new
  @event = current_user.events.build
  1.times {@event.bands.build}
end

如果用户需要在表单中添加新的标注栏,这将非常有效,但是,如果用户不添加新标注栏,则会破坏表单提交。它断开是因为控制器1.times {@event.bands.build}中的行构建了一个新的Band,但提交的表单没有通过Band验证的名称。

为了实现这一点,我需要一种在切换表单的fields_for部分时调用1.times {@event.bands.build}的方法,但我认为这是不可能的。

我尝试在事件模型accepts_nested_attributes_for :bands, reject_if: proc { |attributes| attributes['name'].blank? }中使用reject_if,但它不起作用。我的搜索让我认为这是失败的,因为reject_if直到模型保存后才运行,但Band.name上的验证是在模型保存前运行的?

现在,我把这个放在我的控制器中,所有的测试都通过了:

def create
    @event = current_user.events.build(event_params)
    @event.bands.each do |band|
        if band.name.blank?
            band.destroy
        end
    end
    if @event.save
    blablabla

但这似乎违背了整个瘦控制器、胖模型的方法。

一个简单的解决方法:

对强参数使用两种不同的定义。一个包括一个不包括波段参数。

def event_params
    params.require(:event).permit(:name, :field1, ..., :fieldn)
end
def event_params_with_band
    params.require(:event).permit(:name, :field1, ..., :fieldn, band_attributes: [:name, ..])
end

@event = current_user.events.build(event_params)之前应用一些逻辑来合并或不合并频带参数。例如:

def create
    if params[:event][:new_band]=="true" # let's assume this comes from a 'tick' in your form
        myparams=event_params_with_band
    else
        myparams=event_params
    end
    @event = current_user.events.build(myparams)
    if @event.save
        # your responses etc
    end
end

我想你仍然需要为event_bands建立关系,但我想你知道如何做到这一点。

相关内容

  • 没有找到相关文章

最新更新