阻止从父模型保存的验证,只是删除它们?

时间:2011-07-14 11:40:52

标签: ruby-on-rails ruby-on-rails-3 activerecord

我在我的Rails应用程序中有这些模型(很明显省略了很多东西):

class Invitation < ActiveRecord::Base
  belongs_to :team
  validates :team_id, :presence => true
end

class Team < ActiveRecord::Base
  has_many :invitations
  accepts_nested_attributes_for :invitations

  before_validation :set_invitation_association
  private
    def set_invitation_association
      invitations.each do |invite|
        if invite.new_record?
          # this bit doesn't work since self.id is nil
          invite.team = self
        end
      end
    end
end

现在我要做的就是让current_user在使用嵌套表单创建它的同时邀请人们进入他的团队。

问题当然是当我将团队和邀请属性发布到teams_controller时,邀请失败验证,因为他们没有team_id。但我不能给他们team_id,因为他们所关联的团队没有,因为它还没有保存到数据库。

有没有办法可以实现这一目标,还是只需要从邀请模型中删除验证?我宁愿不这样做,因为我的应用程序中还有其他方法可以发送邀请,我不想让自己开放,以便我可以在没有团队的情况下保存邀请。

或者我只是错误的想法和存在验证只是为了确保用户填写所有字段而不是阻止程序员犯错!?

对于这个狡猾的问题感到抱歉。

<%= form_for(@team) do |f| %>
  <% if @team.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@team.errors.count, "error") %> prohibited this team from being saved:</h2>

      <ul>
      <% @team.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>

  <h3>Invite some teammates</h3>
  <%= f.fields_for :invitations, @invitation do |invite_fields| %>
    <p>
      <%= invite_fields.label :recipient_name %>
      <%= invite_fields.text_field :recipient_name %><br />

      <%= invite_fields.label :recipient_email %>
      <%= invite_fields.text_field :recipient_email %><br />
    </p>
  <% end %>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

1 个答案:

答案 0 :(得分:1)

这里有一个类似的问题:

accepts_nested_attributes_for child association validation failing

你应该放弃我的opnion中team_id的验证。它被ActiveRecord实例化为关系的一部分;作为嵌套表单的结果。如果您在创建团队后创建邀请 - 这似乎很可能 - 然后进行条件验证,其中关联团队不是新记录。

http://railscasts.com/episodes/41-conditional-validations