usando sobre sirve sintaxis rails que programacion para lenguaje introduccion ejemplo aprender ruby-on-rails ruby activerecord has-many-through

ruby-on-rails - sirve - todo sobre ruby on rails



¿Cómo implementar un modelo de amistad en Rails 3 para una aplicación de redes sociales? (5)

La última referencia:

http://railscasts.com/episodes/163-self-referential-association

Actualmente estoy trabajando en una pequeña aplicación de redes sociales y en este momento estoy tratando de crear un modelo que represente amistades entre los usuarios . Esto es lo que se me ocurrió hasta ahora:

class User < ActiveRecord::Base # ... has_many :friendships has_many :friends, :through => :friendships end class Friendship < ActiveRecord::Base belongs_to :user belongs_to :friend, :class_name => ''User'' end

Mi modelo de amistad tiene un campo confirmado como booleano que me gustaría usar para definir una amistad como pendiente o confirmada.

¿Cómo puedo acceder a todas las solicitudes pendientes para un determinado usuario? ¿Puedo definir esto de alguna manera usando el método de alcance de Rails? Algo como

current_user.friendships.requests # => [Friendship, Friendship, ...]

sería genial.

¿Cómo puedo hacer esta asociación bidireccional? Simplemente agrego otra amistad una vez que uno ha confirmado una solicitud de amistad tal que mi tabla de amistad se vea similar a esto:

| user_id | friend_id | confirmed | ----------------------------------- | 1 | 2 | true | | 2 | 1 | true |



Para acceder a todas las amistades pendientes puedes usar una asociación:

has_many :pending_friends, :through => :friendships, :source => :friend, :conditions => "confirmed = 0" # assuming 0 means ''pending''

Para hacer que la amistad sea bidireccional, puede reemplazar su columna confirmada booleana por una columna de estado de cadena que tenga uno de los tres valores siguientes: ''pendiente'', ''solicitada'' y ''aceptada'' (opcionalmente ''rechazada''). Esto ayudará a mantener un registro de quién hizo la solicitud de amistad.

Cuando se envía una solicitud de amistad (por ejemplo, de Foo a Bar), se crean dos registros de amistad (encapsulados en una transacción): uno solicitado y otro pendiente para reflejar la resp. que Bar tiene una amistad solicitada de Foo y Foo tiene una amistad pendiente con Bar.

def self.request(user, friend) unless user == friend or Friendship.exists?(user, friend) transaction do create(:user => user, :friend => friend, :status => ''pending'') create(:user => friend, :friend => user, :status => ''requested'') end end end

Cuando se acepta la amistad (por ejemplo, por Bar), ambos registros de amistad se establecen como aceptados.

def self.accept(user, friend) transaction do accepted_at = Time.now accept_one_side(user, friend, accepted_at) accept_one_side(friend, user, accepted_at) end end def self.accept_one_side(user, friend, accepted_at) request = find_by_user_id_and_friend_id(user, friend) request.status = ''accepted'' request.accepted_at = accepted_at request.save! end

Esto se cubre en gran parte en el capítulo 14 del libro Railspace de Michael Hartl y Aurelius Prochazka. Aquí está el código fuente que debería ayudarlo a refinar su solución.


Te recomiendo el libro RailsSpace: Construyendo un sitio web de redes sociales. Explica claramente cómo implementar un modelo de amistad. Aunque no es extensible a otras formas de relación, es bastante aplicable a su problema.


Una respuesta corta es sí. Solo haz otro registro de amistad para representar la asociación bidireccional.

Escribí una gema llamada has_friendship para este tipo de problema. Todo lo que necesita hacer es dejar has_friendship en su modelo, y todas las asociaciones y métodos serán atendidos.

¡Espero que esto ayude!