I have two models
class Owner < ActiveRecord::Base
has_many :dogs
end
class Dog < ActiveRecord::Base
belongs_to :owner
accepts_nested_attributes_for :owner
end
and the tutorials I've seen always created a new instance (through build) of the associated model (@dog.build_owner in the code below)
class DogsController < ApplicationController
def new
@dog = Dog.new
@dog.build_owner
end
end
Is there a way to find an existing model instance (a particular owner in this case) and associate it when creating a new Dog? instead of creating a new owner every time.
My form looks like this:
<h1>Create a new Dog:</h1>
<%= form_for(@dog) do |f|%>
<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 %>
Thank you!
It looks like what you want to use here is ActiveRecord::Relations#find_or_create_by . In your controller, you'll get the name of the owner through your form, and you'll pass that into the find_or_create_by
method like so:
@dog = Dog.new
@dog.owner.find_or_create_by(name: params.dig(:owner, :name))
This method will set the owner
of the new instance of Dog
to either the Owner
that already exists with the name provided, or go ahead and create the new entry in the database and assign the association for you.
Something you probably want to do with this too is to go ahead and make sure that Owner#name
is forced to be unique. find_or_create_by
makes some pretty strong assumptions that there will only every be one instance of what you're looking for, so if there are multiple, you can get indeterminate results. To guarantee uniqueness of name in the Owner
class, you add the following validation
class Owner < ActiveRecord::Base
has_many :dogs
# uniqueness validation of name
validates :name, uniqueness: true
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.