2015-02-14 2 views
7

Nell'applicazione rails ho un modello di team. Il mio file route.rb per le squadre di simile a questa:helper percorso rotaie non riconosciuto nel modello

resources :teams 

Nel mio teams_controller.rb presentare la linea di team_path(Team.first.id) funziona però l'helper team_path url non viene riconosciuto nel mio modello team.rb. Ottengo questo messaggio di errore:

undefined local variable or method `team_path' for # <Class:0x00000101705e98> 
from /usr/local/rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.1.1/lib/active_record/dynamic_matchers.rb:26:in `method_missing' 

Ho bisogno di trovare un modo per il modello di riconoscere l'assistente team_path percorso.

+1

Credo che bisogna evitare l'uso di aiutanti nei tuoi modelli. Gli helper sono utili nelle visualizzazioni e nei controller. Ad ogni modo, qual è il messaggio di errore e in che modo hai intenzione di usare l'helper? –

+0

Di solito sono utili solo nelle viste e nei controller, ma in questo caso particolare ho bisogno del helper del percorso nel mio modello. Ricevo questo errore 'variabile locale non definita o metodo' team_path 'per # da /usr/local/rvm/gems/ruby-1.9.3-p392/gems/activerecord-4.1.1/lib/active_record /dynamic_matchers.rb:26:in 'method_missing'' – user3266824

risposta

12

Si dovrebbe essere in grado di chiamare i url_helpers questo modo:

Rails.application.routes.url_helpers.team_path(Team.first.id) 
+2

Non è certamente "The Rails Way"." –

+1

È assolutamente perfetto per i modelli essere responsabili della conoscenza della propria posizione, ad esempio URL. Doubly true per i modelli correlati a CMS come' Page', 'Article', ecc., Ma va bene per qualsiasi modello con un URL per conoscerlo. –

+0

Grazie per questo Eliot. Mi rimanderò al tuo buon giudizio e modificherò la mia risposta di conseguenza. – trosborn

-1

I modelli non dovrebbero occuparsi di cose come percorsi, reindirizzamenti o qualcuna di quelle cose. Queste cose sono puramente costruzioni della vista o del controller.

Il modello dovrebbe essere proprio questo; un modello della cosa che stai creando. Dovrebbe descrivere completamente questa cosa, permetterti di trovarne delle istanze, apportarvi delle modifiche, eseguire validazioni su di essa ... Ma quel modello non avrebbe alcuna idea di quale percorso dovrebbe essere usato per qualcosa, anche se stesso.

Un proverbio comune nel mondo di Rails è che se hai difficoltà a fare qualcosa (come chiamare un helper di percorso da un modello) lo stai facendo in modo errato. Prendi questo per dire che anche se qualcosa è possibile, se è difficile da fare in Rails, probabilmente non è il modo migliore per farlo.

+1

Sto provando a memorizzare più percorsi di diversi team in una stringa json insieme ad altri attributi di un team e li ho resi a un suggerimento quando un determinato elemento html viene spostato su . Quindi questa non è una tipica situazione di reindirizzamento. Ho creato un metodo nel mio modello che crea questa stringa json con tutti i miei attributi. Il collegamento è qualcosa a cui ho appena pensato e non sono sicuro di come implementare questa logica nel controller senza mettere molta logica pesante nel controller. È più sensato metterlo nella modella per me. – user3266824

+0

Non capisco i downvotes. Sono stanco di rotaie che incoraggiano cattive pratiche. – Papipo

7

consideri la soluzione di questo as suggested in the Rails API docs for ActionDispatch::Routing::UrlFor:

# This generates, among other things, the method <tt>users_path</tt>. By default, 
# this method is accessible from your controllers, views and mailers. If you need 
# to access this auto-generated method from other places (such as a model), then 
# you can do that by including Rails.application.routes.url_helpers in your class: 
# 
# class User < ActiveRecord::Base 
#  include Rails.application.routes.url_helpers 
# 
#  def base_uri 
#  user_path(self) 
#  end 
# end 
# 
# User.find(1).base_uri # => "https://stackoverflow.com/users/1" 

Nel caso del modello Team dalla questione, provate questo:

# app/models/team.rb 
class Team < ActiveRecord::Base 
    include Rails.application.routes.url_helpers 

    def base_uri 
    team_path(self) 
    end 
end 

Ecco una tecnica alternativa che preferisco in quanto aggiunge meno metodi al modello.

evitare il include e utilizzare url_helpers dall'oggetto routes invece:

class Team < ActiveRecord::Base 

    delegate :url_helpers, to: 'Rails.application.routes' 

    def base_uri 
    url_helpers.team_path(self) 
    end 
end