Para interligar tabelas atravez dos "forein_keys", criamos associações enre os modelos.
Existem 3 tipos de associações: 1 para 1, 1 para varios e varios para varios.
Tipo de associação de um objeto para outro. Util para quebrar uma tabela grande em varias partes. Sempre defina os dois lados da associação!
No modelo Subject:
class Subject < ActiveRecord::Base
has_one :page
end
No modelo Page:
class Page < ActiveRecord::Base
has_one :subject, {:foreign_key => "subject_id"}
end
Para utilizar as associações, carregue um objeto e chame o metodo associado para ter o objeto retornado:
subject.page
ou page.subject
As associações de um objeto para varios são muito usadas dentro dos aplicativos em rails. Elas utilizm o termo no plural e retornam um array de objetos.
A classe com o belongs_to
que deve ter o foreign key
No modelo User:
class User < ActiveRecord::Base
has_many :photos
end
No modelo Photo:
class Photo < ActiveRecord::Base
belongs_to :user
end
user.photos
user.photos << photo
user.photos = [photo, photo, photo]
user.photos.delete(photo)
user.photos.clear
user.photos.empty?
user.photos.size
user.photos[1]
Este tipo de associação é utilizada quando um objeto está associado a varios outros objetos, mas não exclusivamente.
Para este tipo de associação, primeiro é necessario criar uma join table, ou seja, uma tabela simples que não tem um primary key e tem apenas duas colunas com os ids dos dois objetos das duas tableas sendo relacionados.
A nova tabela que vai guardar as inforamções da associação tem algumas regras de nomeação especificas:
O nome da tabela vai ser: "posts_tags".
1 - Criar o arquivo de migração:
rails generate migration CreatePostsTagsJoin
2 - Editar o arquivo de migração:
class CreatePostsTagsJoin < ActiveRecord::Migration
def self.up
create_table :posts_tags, :id => false do |t|
t.integer "post_id"
t.integer "tag_id"
end
add_index :posts_tags, ["post_id", "tag_id"]
end
def self.down
drop_table :posts_tags
end
end
3 - Rodar a migração:
rake:db:migrate
4 - No arquivo do modelo Post:
class Post < ActiveRecord::Base
has_and_belongs_to_many :tags
end
5 - No arquivo do modelo Tag:
class Tag < ActiveRecord::Base
has_and_belongs_to_many :blog_posts, :class_name => "Post"
end
Outra maneira de fazer associações de varios objeos para varios outros é criando um modelo proprio para administrar essas associaçãos e outras informações.
A diferença é que a tabela precisa de um primary key e não precisa seguir nenhuma conveção para o nome.
Neste exemplo vamos criar um log de edição das páginas do sistema.
1 - Criar um modelo:
rails generate model PageEdit
2 - Editar o arquivo de migração:
class CreatePageEdits < ActiveRecord::Migration
def self.up
create_table :posts_tags do |t|
t.references :page
t.references :user
t.string "new_content"
t.timestamps
end
add_index :page_edits, ["page_id", "user_id"]
end
def self.down
drop_table :posts_tags
end
end
3 - Rodar a migração:
rake:db:migrate
4 - No arquivo do modelo Page:
class Page < ActiveRecord::Base
has_many :page_edits
end
5 - No arquivo do modelo User:
class User < ActiveRecord::Base
has_many :page_edits
end
6 - No arquivo do modelo PageEdit:
class User < ActiveRecord::Base
belongs_to :page
belongs_to :editor, :class_name => "User", :foreign_key => "user_id"
end