2011-02-07 32 views
10

Actualmente estoy usando una relación estándar de uno-a-uno para manejar relaciones padre/hijo:carriles - relaciones padre/hijo

class Category < ActiveRecord::Base 
    has_one :category 
    belongs_to :category 
end 

¿Existe un método recomendado para hacerlo o Está bien?

Respuesta

18

Usted tendrá que modificar los nombres que está utilizando para conseguir este trabajo - se especifica el nombre de la relación y, a continuación, decirle Ar lo que la clase es:

class Category < ActiveRecord::Base 
    has_one :child, :class_name => "Category" 
    belongs_to :parent, :class_name => "Category" 
end 
+0

¿Cómo encontramos las categorías secundarias para los padres específicos? – demonchand

+0

Puedes simplemente usar parent.child? –

+0

Encuentro que mi mente piensa "has_one: parent; belongs_to:: children", una disposición más sensata para la misma cosa. – slacy

-2

Dado que la relación es simétrica, lo En realidad parece que diferente a lo que escribió Toby, que prefiero el siguiente:

class Category < ActiveRecord::Base 
    has_one :parent, :class_name => "Category" 
    belongs_to :children, :class_name => "Category" 
end 

Por alguna razón "tiene uno de los padres, muchos niños" es la forma en mi mente las cosas, no "tiene muchos padres, sólo un niño"

+2

Esto no tiene ningún sentido para mí. ¿Por qué un objeto pertenecería a sus hijos? Además, el autor afirmó que la relación era uno a uno, por lo que no entiendo por qué la estás pluralizando. – LandonSchropp

+0

esto debería ser exactamente al revés, mire la respuesta -> http://stackoverflow.com/a/38791328/473040 – equivalent8

4

has_many versión:

class Category < ActiveRecord::Base 
    has_many :children, :class_name => "Category" 
    belongs_to :parent, :class_name => "Category" 
end 

#migratio 
class CreateCategories < ActiveRecord::Migration 
def change 
    create_table :categories do |t| 
     t.integer :parent_id 
     t.string :title 

     t.timestamps null: false 
    end 
end 
end 

# RSpec test 
require 'rails_helper' 
RSpec.describe Category do 
    describe '#parent & #children' do 
    it 'should be able to do parent tree' do 
     c1 = Category.new.save! 
     c2 = Category.new(parent: c1).save! 

     expect(c1.children).to include(c2) 
     expect(c2.parent).to eq c1 
    end 
    end 
end 
+0

Usando Rails 5.1.4. Encontré que cuando sigo lo anterior c2.parent me da c1, pero c1.children me da un error: ActiveRecord :: StatementInvalid (Mysql2 :: Error: columna desconocida 'categories.category_id' en 'where clause': categorías de SELECT ' '. * FROM' categories' WHERE 'categories' .category_id' = 5 – guero64

+0

prueba' has_many: children,: class_name => "Category", foreign_key: "id" ' – equivalent8

0

me di cuenta que tenía que hacer un pequeño cambio en la solución de @ equivalent8 para hacer que funcione para los carriles 5 (5.1.4):

class Category < ActiveRecord::Base 
    has_many :children, :class_name => "Category", foreign_key: 'parent_id' 
    belongs_to :parent, :class_name => "Category", foreign_key: 'parent_id', :optional => true 
end 

Sin la declaración foreign_key , Rails intenta encontrar a los niños mediante organization_id en lugar de parent_id y chokes.

Rails también se bloquea sin la declaración :optional => true en la asociación belongs_to ya que belongs_to requiere que se asigne por defecto una instancia en Rails 5. En este caso, debería asignar un número infinito de padres.