2013-07-24 13 views
7

La mia domanda è simile a Build vs new in Rails 3.Build vs new in Rails 4

In Rails 3, è possibile creare un oggetto nella vista per verificare l'autorizzazione tramite cancan.

<% if can? :create, @question.answers.new %> 
    # Code... 
<% end %> 

In Rails 3, la differenza tra .new e .build era che .build aggiunto l'oggetto appena costruito per la raccolta del genitore, che poi comportato una registrazione aggiuntiva nella visualizzazione, che ovviamente non si desiderava.

In Rails 4, tuttavia, entrambi aggiungono l'oggetto alla raccolta, rendendo un record vuoto nella vista.

Qualcuno ha qualche consiglio su come risolvere questo? Verificare se un record è .persisted? nella vista sarebbe un'opzione ma in qualche modo sento che non dovrei farlo.

Edit: Per chiarire, il modello CanCan assomiglia a questo:

can :manage, Answer do |answer| 
    user.belongables.include?(answer.question.try(:belongable)) 
end 

A causa di questo, non posso solo controllare per classe. Un'istanza reale è effettivamente necessaria per confrontare in base alla relazione.

+1

E se fosse possibile? : create, Answer' come un oggetto throw-away? (Sembra che tu possa passare la lezione da qui: https://github.com/ryanb/cancan/wiki/Controllo-Abilità-chiamando-con-classica) – GSP

risposta

2

Potrei risolvere il problema e ho scoperto due modi.

Innanzitutto, come https://github.com/rails/rails/issues/9167 indica che l'utilizzo di scoped risolve questo problema. Quindi, invece sto usando @question.answers.scoped.new. Come ho spiegato, un semplice Answer.new(question: @question) non ha avuto successo poiché c'erano più dati necessari e l'esempio era semplificato.

In secondo luogo, trattenendo il pattern MVC. Il responsabile del trattamento è responsabile della preparazione dei dati. Quindi, quando esegui il loop delle domande, prepari i dati nel controller, ad esempio @answers = @question.answers. Ora, la raccolta @answers non è interessata da .new o .build sull'associazione.

4

Non sono completamente aggiornato su CanCan, ma a meno che la possibilità di creare sia legata a un'istanza specifica @question in CanCan, è possibile controllare direttamente l'autorizzazione rispetto alla classe. Nessuna istanza deve essere costruita e non ci sono oggetti estranei nella tua vista.

<% if can? :create, Answer %> 
    # Code.. 
<% end %> 

https://github.com/ryanb/cancan/wiki/Checking-Abilities#checking-with-class

EDIT:

In base alla modifica, provare a costruire una risposta stand-alone con l'associazione alla domanda che vi serve.

<% if can? :create, Answer.new(question: @question) %> 
    # Code.. 
<% end %> 

questo non dovrebbe, almeno, aggiungere un'istanza Answer alla vostra collezione @question.answers.

+0

Il problema è che le restrizioni possono essere applicate al sottoinsieme di risposte legate a quella domanda specifica, che IMHO richiede un'istanza per verificare. – pduersteler

+0

Forse includere la definizione di abilità CanCan potrebbe fornire ulteriori informazioni? – GSP

+0

Domanda aggiornata. – pduersteler