Pregunta

¿Es posible configurar una doble relación en modelos activerecord a través del comando generate scaffold?

Por ejemplo, si tuviera un modelo User y un modelo PrivateMessage, la mesa pm necesitaría para realizar un seguimiento tanto de la sender y recipient.

Obviamente, para una sola relación acabo gustaría hacer esto:

ruby script/generate scaffold pm title:string content:string user:references

¿Hay una manera similar a la creación de dos relaciones?

Además, hay alguna forma de configurar alias para las relaciones?

Así que en lugar de decir:

@message.user

Puede usar algo como:

@message.sender o @message.recipient

Cualquier consejo sería muy apreciada.

Gracias.

¿Fue útil?

Solución

Agregue esto a su modelo

has_one :sender, :class_name => "User"
has_one :recipient, :class_name => "User"

Y que son capaces de llamar @message.sender y @message.recipient y ambos referencia al modelo de usuario.

En lugar de user:references en su comando de generar lo que se necesita sender:references y recipient:references

Otros consejos

Aquí hay una respuesta completa a esta cuestión, en el caso de personas que visitan esta pregunta son nuevos en Ruby on Rails y teniendo dificultades para poner todo junto (como yo cuando vi por primera vez en esto).

Algunas partes de la solución tienen lugar en sus migraciones y algunos de sus modelos:

migraciones

class CreatePrivateMessages < ActiveRecord::Migration
  def change
    create_table :private_messages do |t|
      t.references :sender
      t.references :recipient
    end
    # Rails 5+ only: add foreign keys
    add_foreign_key :private_messages, :users, column: :sender_id, primary_key: :id
    add_foreign_key :private_messages, :users, column: :recipient_id, primary_key: :id
  end
end

Aquí está especificando que hay dos columnas de esta tabla que se hace referencia como: remitente y del destinatario: Dirección y que mantienen las referencias a otra mesa. Raíles realidad crearán columnas denominadas 'SENDER_ID' y 'recipient_id' para usted. En nuestro caso serán cada fila de referencia en la tabla de usuarios, pero se especifica que en los modelos, no en las migraciones.

Modelos

class PrivateMessage < ActiveRecord::Base
  belongs_to :sender, :class_name => 'User'
  belongs_to :recipient, :class_name => 'User'
end

Aquí está creando una propiedad en el modelo llamado PrivateMessage: emisor, a continuación, se especifica que esta propiedad está relacionada con la clase de usuario. Rieles, al ver el "belongs_to: emisor", buscará una columna de la base de datos llamada "SENDER_ID", que hemos definido anteriormente, y usarlo para almacenar la clave externa. Entonces usted está haciendo exactamente lo mismo para el destinatario.

Esto le permitirá acceder a su remitente y el destinatario, ambas instancias del modelo de usuario, a través de una instancia del modelo PrivateMessage, como esto:

@private_message.sender.name
@private_message.recipient.email

Este es el modelo del usuario:

class User < ActiveRecord::Base
  has_many :sent_private_messages, :class_name => 'PrivateMessage', :foreign_key => 'sender_id'
  has_many :received_private_messages, :class_name => 'PrivateMessage', :foreign_key => 'recipient_id'
end

Aquí está creando una propiedad en el Modelo de usuario llamado: sent_private_messages, especificando que esta propiedad está relacionada con el modelo PrivateMessage, y que la clave externa en el modelo PrivateMessage que se refiera a esta propiedad se llama 'SENDER_ID'. Entonces usted está haciendo lo mismo para los mensajes privados recibidos.

Esto le permite obtener todos los usuarios de un enviado o recibido mensajes privados haciendo algo como esto:

@user.sent_private_messages
@user.received_private_messages

Hacer cualquiera de estos devolverá un conjunto de instancias de modelo PrivateMessage.

....

Hola tener ambos una relación lado a hacer como abajo en sus dos modelos:

class Message < ActiveRecord::Base

 belongs_to     :sender,
                :class_name => "User",
                :foreign_key  => "sender_id"

 belongs_to     :recipient,
                :class_name => "User",
                :foreign_key  => "recipient_id" 
end

class User < ActiveRecord::Base

  has_many      :sent, 
                :class_name => "Message",
                :foreign_key  => "sent_id"

  has_many      :received, 
                :class_name => "Message", 
                :foreign_key  => "received_id"
end

Espero que esto le ayude a ...

Las respuestas anteriores, mientras excelente, no crean limitaciones extranjeros clave en la base de datos, en lugar sólo la creación de índices y columnas BIGINT. Para asegurar que la restricción de clave externa se hace cumplir, añada lo siguiente a la migración:

class CreatePrivateMessages < ActiveRecord::Migration[5.1]
    def change
        create_table :private_messages do |t|
          t.references :sender
          t.references :recipient
        end

        add_foreign_key :private_messages, :users, column: :sender_id, primary_key: :id
        add_foreign_key :private_messages, :users, column: :recipient_id, primary_key: :id
    end
end

Esto asegurará que los índices se crean en el sender_id y recipient_id, así como las restricciones de clave externa en la base de datos que está utilizando.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top