2 votes

Appel d'une méthode d'association ActiveRecord à partir d'un tableau dans Rails 3.2

Objectif : Produire un document Excel avec des informations provenant de 3 modèles associés qui sont similaires à celles de mon tableau HTML. La gemme to_xls requiert ceci comme une liste de tableaux.

https://github.com/splendeo/to_xls

Sortie souhaitée :

(working for both)      (working for both)    (working in HTML, not in Excel)
territory.branch.name    territory.zip    territory.mailedcounts.maximum(:maileddate)
My Branch                90210            2012-05-01
My Branch                90211            2012-05-03
My Branch                90212            

Une branche a plusieurs territoires. Un territoire a plusieurs comptes de messagerie.

Je peux afficher les données correctes dans ma vue grâce aux méthodes ActiveRecord intégrées pour show.html.erb.

<% for territory in @territories %>
<tr>
  <td><%= territory.branch.name %></td>      
  <td><%= territory.zip %></td>
  <td><%= territory.mailedcounts.maximum(:maileddate) %></td>
</tr>
<% end >

Voici ce que j'ai correctement exporté jusqu'à présent

class BranchesController < ApplicationController
.
.
.
 def show
  @branch = Branch.find(params[:id])
  @territories = @branch.territories

  respond_to do |format|
    format.html
    format.xls { 
      send_data @territories.to_xls(:columns => [ { :branch => :name }, :zip ] )
    }
 end
end

Ce qui me donne territory.branch.name et territory.zip qui fonctionnent tous les deux correctement. En partant de territory, je n'arrive pas à trouver comment accéder aux informations de mes comptes de messagerie.

1voto

Chris Mohr Points 1149

L'utilisation d'une portée personnalisée devrait fonctionner pour cela.

class Territory < ActiveRecord::Base
  scope :mailed_counts_max_date, lambda {
    mailcounts.maximum(:maileddate)  
  }
end

Puis dans le contrôleur :

class BranchesController < ApplicationController
 def show
  @branch = Branch.find(params[:id])
  @territories = @branch.territories

  respond_to do |format|
    format.html
    format.xls { 
      send_data @territories.to_xls(:columns => [ { :branch => :name }, :zip, :mailed_counts_max_date ] )
    }
 end
end

1voto

railsdog Points 1408

Avez-vous essayé (totalement non testé)

format.xls {
  # essentially replicate what the view does
  arr = []
  for territory in @territories
    arr << [territory.branch.name, territory.zip,  territory.mailedcounts.maximum(:maileddate)] 
  end
  send_data arr.to_xls
}

S'il (la gemme ?) s'attend à une liste de tableaux, il n'y a rien de sacro-saint à utiliser ActiveRecord....

1voto

Zach Briggs Points 48

Voici la solution qui a fonctionné pour moi. (Après bien plus d'heures d'essais que cela n'aurait dû prendre).

L'astuce consistait à définir une classe dans le modèle Mailedcount, et non dans le modèle Territory.

class Mailedcount < ActiveRecord::Base
.
.
.
  belongs_to :branch
  belongs_to :territory

  class << self
    def max_maileddate
      maximum('maileddate')
    end
  end
end

De retour au contrôleur, je peux maintenant appeler cette méthode.

class BranchesController < ApplicationController
.
.
.
 def show
  @branch = Branch.find(params[:id])
  @territories = @branch.territories

  respond_to do |format|
  format.html
  format.xls { 
    send_data @territories.to_xls(:columns => [ { :branch => :name }, :zip,
                        { :mailedcounts => :max_maileddate } ] )
  }
    end
  end

Je n'ai pas réussi à faire fonctionner une portée ou une méthode dans le modèle Territoire sans reproduire essentiellement la relation avec une autre jointure.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X