Rails协会澄清

时间:2014-09-12 10:16:52

标签: ruby-on-rails ruby activerecord associations

我希望确认以下关联声明是否有效,如果有更有效的方法。

我有一个动物模型,在那里你可以创建一只狗,猫,兔等,我还需要指定动物的品种,所以我想为每种动物品种类型设置一个模型,所以DogBreed例如和然后是Cat Breed。

我原以为每只动物只能有一个品种,所以就像这样的作品

 class Animal
   has_one :dog_breed
   has_one :cat_breed
 end

class DogBreed
  belongs_to :animal
end

class CatBreed
  belongs_to :animal
end

每个模型的Colums将是

Animal
  name
  description
  size
  breed

DogBreed
  name

CatBreed
  name

有没有更好的方法来解决这个问题?

此外,我将为每个品种模型​​的动物模型添加accepts_nested_attributes_for

由于

1 个答案:

答案 0 :(得分:3)

<强> STI

您正在寻找Single Table Inheritance

#app/models/animal.rb
class Animal < ActiveRecord::Base
   has_many :x
end

#app/models/dog.rb
class Dog < Animal
end

#app/models/cat.rb
class Cat < Animal
end

作为名称&#34;单表继承&#34;建议,你的&#34;依赖&#34;模型将继承。这意味着您可以存储名为animals的中心表,您需要添加type

  

$ rails g migration AddTypeToAnimals

#db/migrate/add_type_to_animals.rb
class AddTypeToAnimals
   def change
      add_column :animals, :type, :string
   end
end

-

<强>修正

这种方式非常简单。

您可以免费调用DogCat模型(&#34;范围&#34; Rails工作范围之外的更改不会超出范围)。 type列将自动填充:

#app/controllers/dogs_controller.b
class DogsController < ApplicationController
   def new
      @owner_dog = Dog.new
   end

   def create
      @owner_dog = Dog.new dog_params
      @owner_dog.save
   end

   private

   def dog_params
      params.require(:dog).permit(:x,:y,:z)
   end
end

<强>更新

从我们的Skype演讲中,您可能想要这样做:

#app/models/animal.rb
class Animal < ActiveRecord::Base
   #fields id | breed_id | name | created_at | updated_at
   belongs_to :breed
   delegate :name, to: :breed, prefix: true
end

#app/models/breed.rb
class Breed < ActiveRecord::Base
   #fields id | name | created_at | updated_at
   has_many :animals
end

这将使您能够使用以下内容:

#app/controllers/animals_controller.rb
class AnimalsController < ApplicationController
   def new 
      @animal = Animal.new
   end

   def create 
      @animal = Animal.new animal_params
   end

   private

   def animal_params
      params.require(:animal).permit(:name, :breed_id)
   end
end

#app/views/animals/new.html.erb
<%= form_for @animal do |f| %>
   <%= f.text_field :name %>
   <%= f.collection_select :breed_id, Breed.all, :id, :name %>
   <%= f.submit %>
<% end %>