Sans connaitre precisement ton schema de base de donnees, je pense que
ce
qu’il te faut c’est le “many-to-many” (n’existe pas tel quel avec
Rails).
De tete et sans tester:
class Lien < ActiveRecord::Base
belongs_to :carnet
belongs_to :fiche
end
class Fiche < ActiveRecord::Base
has_many :liens
has_many :carnets, :through => :liens
end
class Carnet < ActiveRecord::Base
has_many :liens
has_many :fiches, :through => :liens
end
… et maintenant tu veux faire des requetes un peu speciales, tu
rajoutes
cette ligne dans Carnet
pour ta conditions, il faut voir dans les logs de webrick quelle requete
il
te genere et plus particulierement quelles tables il utilise de maniere
a
creer une conditions du type:
[“fiches.annee = 1990”]
Question: annee peut il etre aussi dans Lien ? Auquel cas, cela devient
vraiment simple:
Question: annee peut il etre aussi dans Lien ?
Auquel cas, cela devient vraiment
simple:has_many :carnets_of_1990,
:through=>:liens, :class_name=> “Fiche”,
:conditions=> [“annee = 1990”]
En esperant, que cela t’aide.
N’hesite pas a envoyer ton code + messages d’erreur.a+Â Did
Guide.find(1).carnet_1900
NoMethodError: undefined method carnet_1990' for #<Guide:0x2731698> from /usr/lib/ruby/gems/1.8/gems/ activerecord-1.14.3/lib/active_record/base.rb:1792:inmethod_missing’
from (irb):16
from :0
Guide.find(1).carnet_1900
NoMethodError: undefined method carnet_1990' for #<Guide:0x2731698> from /usr/lib/ruby/gems/1.8/gems/ activerecord-1.14.3/lib/active_record/base.rb:1792:inmethod_missing’
from (irb):16
from :0
Aie, je suis perdu, c’est quoi Guide ??? Guide = Carnet ? Des que tu
auras
resole ce probleme de NoMethodError, envoie moi la requete sql.
[0mSELECT fiches.* FROM fiches INNER JOIN liens ON
fiches.id = liens.fiche_id WHERE (liens.carnet_id =
e[0m
e[4;36;1mCarnet Load (0.004476)e[0m e[0;1mSELECT
carnets.* FROM carnets INNER JOIN liens ON
carnets.id = liens.carnet_id WHERE (liens.fiche_id = 1) e[0m
e[4;35;1mFiche Load (0.007638)e[0m e[0mSELECT fiches.* FROM
fiches INNER JOIN liens ON fiches.id =
liens.fiche_id WHERE (liens.carnet_id = 1 AND ((annee = ‘1990’)))
allez je t’ai trouve la soluce. De maniere generale et c’est une
convention
(je suis desole pour les pro-Toubon), toutes les variables + noms de
methodes + noms de classe doivent etre en anglais. D’autant plus que M.
Rails utilisent pas mal de raccourcis pour les pluriels et cie.
class Card < ActiveRecord::Base
has_many :subscriptions
has_many :books, :through => :subscriptions
end
class Subscription < ActiveRecord::Base
belongs_to :book
belongs_to :card
end
et la plus importante
class Book < ActiveRecord::Base
has_many :subscriptions
has_many :cards, :through => :subscriptions
def self.find_from_year(year)
self.find(:all, :select => “books.*”,
:include => [ :subscriptions, :cards ], :conditions =>
[‘cards.year= ?’, year])
end
end
et dans ta vue:
<% Book.find_from_year('1990').each do |book| %>
<%=h book.name %>
<% end %>
sinon ceci marche mais tu auras des doublons ========> EN GROS CRADE
—> dans le controller
Card.find(:all, :conditions => “year = ‘1990’”)
—> dans ta vue:
<% @cards.each do |card| %>
<% card.books.each do |book| %>
<%=h book.name %>
<% end %>
<% end %>
A mon avis pour la 1ere solution, tu n’es pas oblige d’utilise un modele
dedie a la relation (subscription dans mon cas), si tu crees juste une
table
books_cards (convention), cela devrait marcher.
toutes les variables + noms de methodes + noms de
classe doivent etre en anglais. D’autant plus que M. >Rails utilisent
pas mal de raccourcis pour les pluriels et cie.
Je suis donc bon pour me refaire mes tables ! Je teste ça et te tiens
au courant, merci.
En fait l’erreur est plutot simple, ton code marche très bien la seul
chose c’est que dans ton code tu cherche avec find toutes les fiches, il
te renvoi donc un tableau ou nil.
Dans ton cas il te faut donc quelque chose du genre:
@fiches = Fiche.find(:all, :conditions => "annees = '1990'")
for fiche in @fiches
@carnetsde1990 << fiche.carnets
end
cela devrai fonctionner.
Pour la petite astuce, tu peux aussi pre-charger les champs fils (soit
les carnets dans ton cas) en ajoutant :include => [:carnets] dans ton
find, cela t’evitera de faire des requettes dans ta boucle.
Ton code deviendrai donc:
@fiches = Fiche.find(:all, :conditions => "annees = '1990'",
:include => [:carnets])
for fiche in @fiches
@carnetsde1990 << fiche.carnets
end
Je pense bloquer sur habtm et array, est-ce que cela sauve mon honneur ?
P.S.: Je viens de me lire la partie sur ActiveRecord de “Agile Web
Development with Rails 2nd ed” et je doit dire que ca aide bien pour ce
genre de problème.
P.S.: Je viens de me lire la partie sur ActiveRecord de “Agile Web
Development with Rails 2nd ed” et je doit dire que ca aide bien pour ce
genre de problème.