Rails:2 个模型,1 个table。单独的表单+控制器。活动记录验证错误后表单呈现错误 model/incorrectly

Rails: 2 models, 1 table. Separate forms + controllers. After active record validation errors form renders wrong model/incorrectly

我有 2 个模型(passsubscription)、2 个控制器和 2 个表单。这些模型共享一个数据库 table。

共享的 table 是 passes。要判断一条记录是否为 subscription,有一列 is_subscription。因此,我的 subscription 模型有以下内容:

      self.table_name = :passes
      default_scope { where(is_subscription: true) }
      validates :name, presence: true

注意 name 上的验证。

subscription形式:

<%= form_for(@subscription, html: {class: "my-class"}) do |f| %>

呈现:

<form class="form-horizontal" id="new_subscription" action="/subscriptions" accept-charset="UTF-8" method="post">
<input class="form-control" type="text" name="subscription[name]" id="subscription_name">
...

在控制器中:

  def show
  end

  def new
    @subscription = Subscription.new
  end

  def create
    @subscription = current_user.company.passes.new(subscription_params)
    if @subscription.save
      redirect_to subscription_path(@subscription), notice: "Yay"
    else
      render :new
    end
  end

一切正常。但是,如果我尝试创建一个新订阅并从表单中省略 name - 这会触发活动记录验证和错误。表单重新呈现,现在已更改:

<form class="form-horizontal" id="new_pass" action="/passes" accept-charset="UTF-8" method="post">
<input class="form-control" type="text" value="" name="pass[name]" id="pass_name">
...

我已经尝试设置 as: "subscription" 来修复除了动作之外的所有问题。如果我设置 action: 操作仍然被覆盖。

希望对如何最好地处理此问题有一些见解。不幸的是,我没有能力改变 table 的情况(即使用单独的 tables)。

您可以使用 form_tag 而不是 form_for。前者不关心正在使用的模型对象——事实上你甚至不传递它。这将要求你使用通用的 text_field_tag 等助手而不是你可能会使用的 form.text_field :foo现在正在使用。

但它可以让你回避这个问题。

我不知道你为什么在提交订阅时创建一个通行证(你说你有 2 个控制器,但看起来你只为两个控制器使用一个控制器(?))。

如果无法保存通行证,我会设置一个订阅对象:

def create
  @subscription = Pass.new(subscription_params)
  if @subscription.save
    redirect_to subscription_path(@subscription), notice: "Yay"
  else
    @subscription = Subscription.new(subscription_params)
    render :new
  end
end

这样您就可以订阅您正在使用的变量。

编辑:另外,检查 activerecord 对单一 Table 继承的支持,它可以帮助您清理模型 https://edgeguides.rubyonrails.org/association_basics.html#single-table-inheritance