誰かがオブジェクトの配列で will_paginate を使用する方法を説明できるかどうか疑問に思っていましたか?
たとえば、私のサイトには、ユーザーが意見を評価できる意見セクションがあります。以下は、意見を評価したユーザーを集めるために書いた方法です。
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
ありがとうございました
will_paginate 3.0は、新しいActiveRecord::Relation
in Rails3。したがって、デフォルトではリレーションに対してのみpaginate
を定義します。それでも配列を使用できますが、Railsその部分を要求する。
config/initializers
(私はwill_paginate_array_fix.rb
)、 これを追加
require 'will_paginate/array'
その後、配列で使用できます
my_array.paginate(:page => x, :per_page => y)
_Array#from
_を使用してページネーションをシミュレートすることもできますが、実際の問題は、Array
を使用しないことです。
これは、ActiveRecord Associationsの目的です。このガイドを注意深く読んでください。Railsアプリケーションを開発している場合に知っておく必要がある多くの有用なものがあります。
同じことをするより良い方法を示しましょう:
_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
_
データベーススキーマが適切な命名規則に従っていることが重要です。そうしないと、すべてが破られます。テーブルを手動で作成するのではなく、データベース移行で作成していることを確認してください。
これらの関連付けにより、モデルにヘルパーが作成され、検索がはるかに簡単になります。 OpinionRatingsのリストを反復してユーザーを手動で収集する代わりに、Railsを_named_scope
_またはscope
を使用してこれを行うことができますre using Rails 2.3または3.0。指定しなかったため、両方の例を示します。これをOpinionRatingクラスに追加します。
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
_
いずれの場合でも、OpinionRatings
モデルでfor(id)
を呼び出して、IDを渡すことができます。
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)
_
これらすべての結果は、簡単にページ分割できるようになったことです。
_@ratings = @ratings.paginate(:page => params[:page])
_
Rails 4.x:ほぼ同じ:
_scope :agreed, ->{ where agreed: true }
def self.for(id)
joins(:opinion).where(opinion: { id: id })
end
_
新しいRailsの場合、私の好みは kaminari ページネーションの場合:
_@ratings = @ratings.page(params[:page])
_
宝石will_paginate
は、ActiveRecordクエリと配列の両方をページ分割します。
list = OpinionRating.where(:opinion_id => params[:id]).includes(:profile).paginate(:page => params[:page])
@agree_list = list.map(&:profile)
構成ファイルを使用したくない場合や問題がある場合は、配列ではなくActiveRecord :: Relationを返すようにすることもできます。例えば、agree_listをユーザーIDのリストに変更し、それらのIDでINを実行して関係を返します。
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
これはデータベースの観点からは非効率的ですが、will_paginate構成ファイルに問題がある人にとってはオプションです。
私はRails 3 Ruby 1.9.2。を使用しています。また、アプリを起動しているだけなので、CSSやスタイルは含まれていません。
will_paginateをインストール:
gem install will_paginate
Gemfileに追加してバンドルを実行します。
コントローラー
class DashboardController < ApplicationController
include StructHelper
def show
@myData =structHelperGet.paginate(:page => params[:page])
end
end
モジュールStructHelperは、データベースではなくサービスを照会します。 structHelperGet()は、レコードの配列を返します。
より洗練されたソリューションがモデルを偽造するのか、データを時々取得して、時々sqlliteテーブルを再作成し、実際のモデルを照会するのかどうかはわかりません。私の最初のRailsアプリを作成するだけです。
表示
<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>
これにより、ページごとにデフォルトの30行のページネーションが提供されます。
http://railstutorial.org をまだ読んでいない場合は、今すぐ読み始めてください。
Gemがなくてもページネーションを実装できます。これを見ました 配列のページネーションはどうすればいいですか? 。 kaminari gems docでの簡単な実装。 kaminari gems docから取得した以下の例を参照してください
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]
Railsアソシエーションを利用して、新しいメソッドを思い付きました:
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
私の見解では、次のようにプロファイルを調べました:
<% @agree_list.each do |rating| %>
<% user = Profile.find(rating.profile_id) %>
<% end %>
これを行うより良い方法があれば投稿してください。 OpinionRatingモデルでnamed_scopeヘルパーを使用しようとしましたが、うまくいきませんでした。ここに私が試したものの例がありますが、動作しません:
named_scope :with_profile, lambda {|id| { :joins => [:profile], :conditions => ['profile_id = ?', id] } }
ただし、findメソッドを使用するのと同じように見えました。
すべての助けてくれてありがとう。