Ich habe mich gefragt, ob jemand erklären kann, wie man will_paginate für ein Array von Objekten verwendet.
Auf meiner Website habe ich beispielsweise einen Meinungsbereich, in dem Benutzer die Meinungen bewerten können. Hier ist eine Methode, die ich geschrieben habe, um die Benutzer zu sammeln, die die Meinung bewertet haben:
def agree_list
list = OpinionRating.find_all_by_opinion_id(params[:id])
@agree_list = []
list.each do |r|
user = Profile.find(r.profile_id)
@agree_list << user
end
end
Vielen Dank
Antworten:
will_paginate 3.0 wurde entwickelt, um die Vorteile von
ActiveRecord::Relation
Rails 3 zu nutzen. Daherpaginate
werden standardmäßig nur Relationen definiert . Es kann immer noch mit einem Array funktionieren, aber Sie müssen den Schienen mitteilen, dass sie dieses Teil benötigen.Fügen Sie dies in einer Datei in Ihrer
config/initializers
(von mir verwendetenwill_paginate_array_fix.rb
) hinzurequire 'will_paginate/array'
Dann können Sie auf Arrays verwenden
my_array.paginate(:page => x, :per_page => y)
quelle
Sie könnten verwenden
Array#from
, um die Paginierung zu simulieren, aber das eigentliche Problem hier ist, dass Sie überhaupt nicht verwenden solltenArray
.Dafür sind ActiveRecord- Zuordnungen gemacht. Sie sollten diese Anleitung sorgfältig lesen. Es gibt viele nützliche Dinge, die Sie wissen müssen, wenn Sie Rails-Anwendungen entwickeln.
Lassen Sie mich Ihnen einen besseren Weg zeigen, dasselbe zu tun:
class Profile < ActiveRecord::Base has_many :opinion_ratings has_many :opinions, :through => :opinion_ratings end class Opinion < ActiveRecord::Base has_many :opinion_ratings end class OpinionRating < ActiveRecord::Base belongs_to :opinion belongs_to :profile end
Es ist wichtig, dass Ihr Datenbankschema den richtigen Namenskonventionen folgt, da sonst alles kaputt geht. Stellen Sie sicher, dass Sie Ihre Tabellen mit Datenbankmigrationen erstellen anstatt sie manuell auszuführen.
Diese Zuordnungen erstellen Helfer für Ihre Modelle, um die Suche erheblich zu vereinfachen. Anstatt eine Liste von OpinionRatings zu iterieren und die Benutzer manuell zu sammeln, können Sie Rails dazu bringen, dies für Sie zu tun, indem Sie Rails 2.3 oder 3.0 verwenden
named_scope
oder davonscope
abhängen, ob Sie Rails 2.3 oder 3.0 verwenden. Da Sie nicht angegeben haben, werde ich beide Beispiele geben. Fügen Sie dies Ihrer OpinionRating-Klasse hinzu:2.3
named_scope :for, lambda {|id| { :joins => :opinion, :conditions => { :opinion => { :id => id } } } } named_scope :agreed, :conditions => { :agree => true } named_scope :with_profiles, :includes => :profile
3.0
scope :agreed, where(:agree => true) def self.for(id) joins(:opinion).where(:opinion => { :id => id }) end
In jedem Fall können Sie anrufen
for(id)
auf demOpinionRatings
Modell und ihm eine ID übergeben:2.3
@ratings = OpinionRating.agreed.for(params[:id]).with_profiles @profiles = @ratings.collect(&:profile)
3.0
@ratings = OpinionRating.agreed.for(params[:id]).includes(:profile) @profiles = @ratings.collect(&:profile)
Das Ergebnis all dessen ist, dass Sie jetzt leicht paginieren können:
@ratings = @ratings.paginate(:page => params[:page])
Update für Rails 4.x: mehr oder weniger gleich:
scope :agreed, ->{ where agreed: true } def self.for(id) joins(:opinion).where(opinion: { id: id }) end
Obwohl ich für neuere Rails Kaminari für die Paginierung bevorzuge :
@ratings = @ratings.page(params[:page])
quelle
Der Edelstein
will_paginate
paginiert sowohl ActiveRecord-Abfragen als auch Arrays.list = OpinionRating.where(:opinion_id => params[:id]).includes(:profile).paginate(:page => params[:page]) @agree_list = list.map(&:profile)
quelle
Wenn Sie die Konfigurationsdatei nicht verwenden möchten oder Probleme damit haben, können Sie auch nur sicherstellen, dass Sie eine ActiveRecord :: Relation anstelle eines Arrays zurückgeben. Ändern Sie beispielsweise die Vereinbarung_Liste in eine Liste von Benutzer-IDs und führen Sie dann ein IN für diese IDs durch, um eine Beziehung zurückzugeben.
def agree_list list = OpinionRating.find_all_by_opinion_id(params[:id]) @agree_id_list = [] list.each do |r| user = Profile.find(r.profile_id) @agree_id_list << user.id end @agree_list = User.where(:id => @agree_id_list) end
Dies ist aus Datenbanksicht ineffizient, aber eine Option für alle, die Probleme mit der Konfigurationsdatei will_paginate haben.
quelle
Ich nutzte die Schienenverbände und fand eine neue Methode:
def agree_list o = Opinion.find(params[:id]) @agree_list = o.opinion_ratings(:conditions => {:agree => true}, :order => 'created_at DESC').paginate :page => params[:page] rescue ActiveRecord::RecordNotFound redirect_to(profile_opinion_path(session[:user])) end
Aus meiner Sicht habe ich das Profil folgendermaßen nachgeschlagen:
<% @agree_list.each do |rating| %> <% user = Profile.find(rating.profile_id) %> <% end %>
Bitte posten Sie, wenn es einen besseren Weg gibt, dies zu tun. Ich habe ohne Glück versucht, den Helfer named_scope im OpinionRating-Modell zu verwenden. Hier ist ein Beispiel für das, was ich versucht habe, aber nicht funktioniert:
named_scope :with_profile, lambda {|id| { :joins => [:profile], :conditions => ['profile_id = ?', id] } }
Das schien jedoch dasselbe zu sein wie die Find-Methode.
Danke für all die Hilfe.
quelle
Ich benutze Schienen 3 Rubin 1.9.2. Außerdem starte ich gerade die App, sodass keine CSS oder Stile enthalten sind.
Installieren Sie will_paginate:
gem install will_paginate
Zu Gemfile hinzufügen und Bundle ausführen.
Regler
class DashboardController < ApplicationController include StructHelper def show @myData =structHelperGet.paginate(:page => params[:page]) end end
Das Modul StructHelper fragt einen Dienst ab, keine Datenbank. structHelperGet () gibt ein Array von Datensätzen zurück.
Ich bin mir nicht sicher, ob eine komplexere Lösung darin besteht, ein Modell zu fälschen oder die Daten von Zeit zu Zeit abzurufen und ab und zu eine SQLite-Tabelle neu zu erstellen und ein echtes Modell zum Abfragen zu haben. Ich erstelle gerade meine erste Rails-App.
Aussicht
<div id="Data"> <%= will_paginate @myData%> <table> <thead> <tr> <th>col 1</th> <th>Col 2</th> <th>Col 3</th> <th>Col 4</th> </tr> </thead> </tbody> <% @myData.each do |app| %> <tr> <td><%=app[:col1]%> </td> <td><%=app[:col2]%> </td> <td><%=app[:col3]%> </td> <td><%=app[:col4]%> </td> </tr> <% end %> </tbody> </table> <%= will_paginate @myData%> </div>
Dadurch erhalten Sie eine Pagnation der Standardzeilen von 30 Zeilen pro Seite.
Wenn Sie http://railstutorial.org noch nicht gelesen haben, lesen Sie es jetzt.
quelle
Sie können die Paginierung auch ohne Edelstein implementieren. Ich habe dies gesehen. Wie paginiere ich ein Array? . Einfache Implementierung in Kaminari Gems Doc. Bitte sehen Sie das folgende Beispiel, das ich von Kaminari Gems Doc erhalten habe
arr = (1..100).to_a page, per_page = 1, 10 arr[((page - 1) * per_page)...(page * per_page)] #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] page, per_page = 2, 10 arr[((page - 1) * per_page)...(page * per_page)] #=> [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
quelle