Pergunta

Outra questão básica Rails:

Eu tenho uma tabela de banco de dados que precisa conter referências a exatamente dois registros diferentes de um tipo de dados específico.

hipotético exemplo: Eu estou fazendo um banco de dados de vídeo game. Eu tenho uma tabela de "Empresas". Quero ter exatamente um desenvolvedor e exatamente um editor para cada entrada "Videogame".

Eu sei que se eu quero ter uma empresa, eu só posso fazer algo como:

script/generate Videogame company:references

Mas eu preciso ter ambas as empresas. Eu prefiro não usar uma tabela de junção, como só pode haver exatamente dois do determinado tipo de dados, e eu preciso que eles sejam distintos.

Parece que a resposta deve ser bastante óbvio, mas não posso encontrá-lo em qualquer lugar na Internet.

Foi útil?

Solução

Apenas para arrumar as coisas um pouco, em sua migração agora você pode também fazer:

create_table :videogames do |t|
  t.belongs_to :developer
  t.belongs_to :publisher
end

E uma vez que você está chamando as chaves developer_id e publisher_id, o modelo provavelmente deve ser:

belongs_to :developer, :class_name => "Company"
belongs_to :publisher, :class_name => "Company"

Não é um grande problema, mas eu acho que, como o número de associações com argumentos extras são adicionados, as coisas menos claras tornam-se, por isso é melhor ficar com os padrões sempre que possível.

Outras dicas

Eu não tenho nenhuma idéia de como fazer isso com script / gerar.

A ideia subjacente é mais fácil mostrar sem o uso de script / gerar qualquer maneira. Você quer dois campos na sua tabela de videogames / modelo que detêm as chaves estrangeiras para a empresas de tabela / modelo.

Eu vou te mostrar o que eu pense o código ficaria assim, mas eu não testei isso, para que eu pudesse estar errado.

Seu arquivo de migração tem:

create_table :videogames do |t|
  # all your other fields
  t.int :developer_id
  t.int :publisher_id
end

Então, em seu modelo:

belongs_to :developer, class_name: "Company", foreign_key: "developer_id"
belongs_to :publisher, class_name: "Company", foreign_key: "publisher_id"

Você também mencionam que querem as duas empresas sejam distintos, o que você poderia segurar em uma validação no modelo que os controlos que developer_id != publisher_id.

Se houver quaisquer métodos ou validação que você quer específica para um determinado tipo de empresa, você poderia subclasse o modelo de empresa. Este emprega uma técnica chamada herança única tabela. Para mais informações confira este artigo: http://wiki.rubyonrails.org/rails/pages/ singletableinheritance

Você teria, então:

#db/migrate/###_create_companies
class CreateCompanies < ActiveRecord::Migration
  def self.up
    create_table :companies do |t|
      t.string :type  # required so rails know what type of company a record is
      t.timestamps
    end
  end

  def self.down
    drop_table :companies
  end
end

#db/migrate/###_create_videogames
class CreateVideogames < ActiveRecord::Migration
  create_table :videogames do |t|
    t.belongs_to :developer
    t.belongs_to :publisher
  end    

  def self.down
    drop_table :videogames
  end
end

#app/models/company.rb
class Company < ActiveRecord::Base 
  has_many :videogames
  common validations and methods
end

#app/models/developer.rb
class Developer < Company
  developer specific code
end

#app/models/publisher.rb
class Publisher < Company
  publisher specific code
end

#app/models/videogame.rb
class Videogame < ActiveRecord::Base 
  belongs_to :developer, :publisher
end

Como resultado, você teria Companhia, desenvolvedor e editor modelos para uso.

 Company.find(:all)
 Developer.find(:all)
 Publisher.find(:all)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top