Rails e Mongoid il modo migliore per implementare il sistema di condivisione

4

Devo modellare Utente e Consiglio su rotaie usando mongoid come ODM.

Ogni scheda fa riferimento a un utente tramite una chiave esterna user_id e ora voglio aggiungere la possibilità di condividere una scheda con altri utenti.

Seguendo CRUD, creerei un nuovo modello chiamato qualcosa come Condividi ed è collegato Controller con la possibilità di creare / modificare / eliminare una condivisione ma ho alcuni dubbi:

  1. In primo luogo, dove salvare informazioni su Azioni ? Penso che potrei creare un campo nella raccolta della commissione chiamata shared_with che include una serie di ID utente. in MySQL ho creato una nuova tabella con gli id di chi condivide, la risorsa condivisa e l'utente con cui le risorse sono condivise, ma non credo che sia necessario utilizzare MongoDB.
  2. Ogni utente a cui è condivisa una scheda deve essere in grado di modificare la scheda (ma non di eliminarla) in modo che la commissione abbia due relazioni una con il proprietario e un'altra con gli utenti con cui la scheda è condivisa, giusto?
  3. Per permesso (il proprietario dovrebbe essere in grado di eliminare una scheda ma gli utenti con cui è condiviso non dovrebbero) cosa usare? Sto usando Devise per l'autenticazione ma penso che qualcosa come CanCan si adatterebbe meglio. ma come implementarlo?

Cosa ne pensi di questo modo? Trovi problemi o hai soluzioni migliori?

    
posta Matteo Pagliazzi 31.03.2012 - 19:19
fonte

2 risposte

4

In genere sono d'accordo con la tua soluzione e farei lo stesso, cioè creare un modello separato chiamato Share, anche se sembra una soluzione simile a RDBMS.

Ma facciamo un passo indietro e rivediamo le opzioni disponibili.

Prima di tutto, considera le relazioni dei tuoi modelli. Disegnali su un foglio di carta e osserva il tipo di relazioni e le loro associazioni (appartiene a, ne ha una, ne ha molte, ne ha molte attraverso o has_and_belongs_to_many). Il riferimento perfetto per le associazioni nei binari è link . Prendi in considerazione che Mongoid offre anche un tipo di relazioni embedded_in / embeds_many.

Nel tuo caso le relazioni sarebbero: Utente (1..N) Schede per possedere, Schede Utente (N.N) per la condivisione.

Il suggerimento per decidere se usare has_many, has_and_belongs_to_many o embeds_many è se il modello subordinato rappresenta o meno un tipo di relazione semanticamente incorporato e non è connesso ad altri modelli rispetto al suo genitore. È, usa embeds_many, altrimenti usa has_many o has_and_belongs_to_many.

Il suggerimento per decidere se usare has_many: through o has_and_belongs_to_many è se vuoi aggiungere più dati a un modello di collegamento (Condividi nel tuo caso).

has_and_belongs_to_many in mongoid sta facendo senza la creazione di un modello di collegamento, cioè i board_ids sarebbero mantenuti come una matrice nel modello User e user_ids sarebbero mantenuti come una matrice nel modello Board.

Il motivo per non utilizzare HABTM nel tuo caso è semplice. Hai due relazioni tra i tuoi modelli User e Board (condivisione e possessione), avresti difficoltà a capire quale espressione come user.boards significhi (schede condivise o schede di proprietà). Non conosco un modo semplice per separare questi due tipi di relazioni senza utilizzare un terzo modello (Condividi) come proposto nei commenti (utilizzando :as , ecc.)

Puoi anche mantenere manualmente gli ID delle schede nel tuo modello utente, in questo modo:

class User
  include Mongoid::Document
  field :name
  key :shared_board_ids, Array, :index => true
  key :owned_board_ids, Array, :index => true

  def shared_boards
    Board.find shared_board_ids
  end
  # ...

end

Tuttavia, le difficoltà in questo caso si presentano abbastanza velocemente. Devi distruggere manualmente tutti i riferimenti della board dal modello User quando distruggi una board. Se si mantiene un shared_user_ids nel modello Board, si ha ridondanza e un altro insieme di difficoltà.

Quindi, sì, ti consiglio di creare un modello di condivisione separato, come mostrato di seguito.

class User
  include Mongoid::Document
  field :name
  has_many :shares
  has_many :boards
end

class Board
  include Mongoid::Document  
  field :title
  has_many :shares
  belongs_to :user
end

class Share
  include Mongoid::Document  
  belongs_to :user
  belongs_to :board
end

Come le autorizzazioni, CanCan è semplice, ma sta andando bene. Si noti una differenza tra l'autenticazione dei termini (che controlla l'autenticità di un utente, in altre parole controlla che l'utente sia realmente chi afferma di essere, normalmente utilizzando la password) e l'autorizzazione (che controlla i diritti dell'utente). L'autenticazione è gestita da gemme come Authlogic, Warden (e Devise basato su Warden), Stregoneria. L'autorizzazione è gestita da Declarative_authorization o CanCan.

    
risposta data 14.04.2012 - 18:10
fonte
0

Penso che potresti trovare risposte migliori su StackOverflow. Non sono un esperto di RAILS o mongodb, ma ci proverò.

  1. Creare un campo nella collezione della Board probabilmente funzionerebbe OK.

  2. Potresti voler creare una raccolta di relazioni singole e avere un tipo aggiunto alla relazione. In questo modo potresti avere più proprietari se lo desideri e potresti aggiungere altri tipi in un secondo momento, ad esempio "di sola lettura" o "bloccato".

  3. Verifica il tipo e il rendering delle viste in base al fatto che siano condivise o meno e se siano o meno proprietari. Non penso che tu abbia bisogno di un framework di permessi per questo, ma questo non significa che sia una cattiva idea metterne uno in.

Spero che ti aiuti!

    
risposta data 12.04.2012 - 21:53
fonte

Leggi altre domande sui tag