2014-09-12 97 views
2

我在尋找確認下面的關聯聲明是否可以工作,如果有更有效的方法做到這一點。Rails協會澄清

我有一個動物模型,在那裏你可以創建一個狗,貓,兔子等,我也需要指定動物是什麼品種,所以我想爲每個動物品種類型設置一個模型,所以DogBreed例如然後是貓品種。

我想,每個動物只能有一個品種,所以會像這樣工作

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就動物模型爲每個品種型號

感謝

+0

+1爲您持續堅持與Rails! – 2014-09-12 10:19:22

+0

爲你寫作答案 – 2014-09-12 10:20:26

+0

你對每個模型有什麼其他專欄? – 2014-09-12 10:27:16

回答

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 

由於名稱「單表繼承」建議,您的「依賴」模型將繼承自。這意味着你將能夠存儲所謂animals中央表,在其中你需要添加一個type

$軌摹遷移AddTypeToAnimals

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

-

修復

這種工作方式其實很簡單。

你可以打電話給你的DogCat模型不受懲罰(沒有改變超出「正常」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 %> 
+1

隨着更新的問題你的解決方案,只需要在動物身上有一個「品種」字符串類型,而不是通過一個選擇來設置的關聯,而選擇是由相應模型的選項填充的。 – 2014-09-12 10:34:34

+0

是的,這正是我想要實現的,所以我可以使用accep_nested_attributes_for與來自animal_breed模型的belongs_to關係? – Richlewis 2014-09-12 10:39:59

+0

是的,我認爲我在更新中解決了這個問題。雖然是一個更簡單的解決方案,但我相信這是您提供的新環境所需要的 – 2014-09-12 10:42:50