1

我有两个模型,狗和主人,我希望他们的名字相同,如果我要求填写两次字段(一次是狗,另一次是主人),那将是多余的。我想知道是否有一种更简单的方法可以用一个输入更新两个数据库。

<h1>Create a new Dog:</h1>
<%= form_for(@dog) do |f|%>
  <div>
    <%= f.label :name%>
    <%= f.text_field :name%>
  </div><br>
    
  <div>
    <%= f.label :breed%>
    <%= f.text_field :breed%>
  </div><br>
    
  <div>
    <%= f.label :age%>
    <%= f.text_field :age%>
  </div><br>
    
  <div>
    <h3>create a new owner:</h3>
    <%= f.fields_for :owner, Owner.new do |owner_attributes|%>
        <%= owner_attributes.label :name, "Owner Name:" %>
        <%= owner_attributes.text_field :name %>
    <% end %>
  </div>
    
  <%= f.submit %>
    
<% end %>
4

2 回答 2

1

首先,不知道为什么要保持主人和狗的名字相同。

但是,有很多方法可以实现您想要的:

  1. 您可以简单地从表单中省略所有者名称。

所以你不再需要:<%= owner_attributes.label :name, "Owner Name:" %> 或者你不再需要:

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

在 Owner/Dog 模型中,您可以在回调中传递狗/所有者的名称 - 可能是 after_initialize 或 before_save 或 before_validation,具体取决于您的验证要求。

class Dog
  belongs_to :owner
  before_validation :set_name

  private

  def set_name
    self.name = owner&.name
  end
end
  1. 您可以将所有者名称改为隐藏字段,并且可以编写一些 javascript 以在提交表单或onblur事件之前使用狗名更新隐藏字段。我更喜欢第一种方法,因为它比保持数据库一致性的 JS 解决方案更简单、更安全
于 2020-07-18T21:21:06.550 回答
0

如果是狗belongs_to和主人,你真的不需要单独存储主人的名字。您可以在dog.owner.name任何有Dog实例的地方调用。话虽如此,使用以下方法在控制器中的 POSTed 表单值之上附加属性相对简单.merge()

def create
  @dog = Dog.new(dog_params.merge(owner: params[:dog][:owner])[:name])
  if @dog.save
    ...
  end
end

def dog_params
  params.require(:dog).permit(:name, :breed, :age, owner: %i[name])
end
于 2020-07-18T22:05:11.600 回答