私はRailsで新しいです...笑顔Rails:私のショービューに "次の投稿"と "以前の投稿"のリンクはありますか?
私のブログでは、私は自分のショービューの一番下に "前の投稿"リンクと "次の投稿"リンクを持っています。
どうすればよいですか?
ありがとうございます!
私はRailsで新しいです...笑顔Rails:私のショービューに "次の投稿"と "以前の投稿"のリンクはありますか?
私のブログでは、私は自分のショービューの一番下に "前の投稿"リンクと "次の投稿"リンクを持っています。
どうすればよいですか?
ありがとうございます!
各タイトルはユニークであり、あなたはアルファベットが必要な場合は、お使いのPost
モデルでこれを試してみてください。
def previous_post
self.class.first(:conditions => ["title < ?", title], :order => "title desc")
end
def next_post
self.class.first(:conditions => ["title > ?", title], :order => "title asc")
end
ビュー内のものにリンクすることができます。
<%= link_to("Previous Post", @post.previous_post) if @post.previous_post %>
<%= link_to("Next Post", @post.next_post) if @post.next_post %>
未テストですが、あなたに近づくはずです。別のソート順が必要な場合は、title
を一意の属性(created_at
、id
など)に変更できます。
"prev"と "next"のそれぞれに1つずつ、2つのクエリを実行するだけです。 created_atカラムがあると仮定します。
擬コード:もちろん
# get prev
select * from posts where created_at < #{this_post.created_at} order by created_at desc limit 1
# get next
select * from posts where created_at > #{this_post.created_at} order by created_at desc limit 1
現在のポストである "this_post"。
あなたの投稿がauto_incrementカラムに保存されていて、IDを再利用しない場合は、created_atの代わりにidカラムを使用するだけで済みます。idカラムはすでに索引付けされているはずです。 created_atカラムを使用する場合は、そのカラムにインデックスを置くことが間違いないでしょう。
あなたが同様で順番を必要としています... –
うんは、あなたは正しい、によって順序が必要とされています。私は自分の反応を更新しました。 –
あなたを賞賛してください!しかし、必要ならば、次のまたは前のアルファベット順を検出してください: – pollinoco
will_paginateを試してみてください。投稿エントリのページを設定するために必要なすべての機能を提供します。 learn here too
次のボタンと前のボタンを追加したい場合は、hereも参照できます。
will_paginateはこの問題にはあまり適していません。投稿を表示しているときは、コレクションではなく個々の投稿を扱っています。 –
これが私のやり方です。まず、あなたのPost
モデルにnamed scopesのカップルを追加します:あなたはおそらくちょうどリンクを示すためにフル実装Post
インスタンスを取得したくないので
def previous
Post.find_by_id(id - 1, :select => 'title, slug etc...')
end
def next
Post.find_by_id(id + 1, :select => 'title, slug etc...')
end
は、フィールドを制限する:select
オプションの使用に注意してください。
はその後、私のposts_helper
に、私はこの方法があります:
def sidebar_navigation_links
next_post = @post.next
previous_post = @post.previous
links = ''
if previous_post
links << content_tag(:h3, 'Previous')
links << content_tag(:ul, content_tag(:li,
content_tag(:a, previous_post.title,
:href => previous_post.permalink)))
end
if next_post
links << content_tag(:h3, 'Next', :class => 'next') if previous_post
links << content_tag(:h3, 'Next') if previous_post.nil?
links << content_tag(:ul, content_tag(:li,
content_tag(:a, next_post.title,
:href => next_post.permalink)))
end
content_tag(:div, links)
end
を、私は、これはそれほど冗長であることをリファクタリングすることができ確信しているが、意図は明確です。明らかにマークアップの要件は私のものとは異なるので、たとえば、順序付けられていないリストの使用を選択することはできません。
重要なことは、if
ステートメントを使用することです。最初の投稿をしていれば、前の投稿はなく、逆に、最後の投稿の場合は次の投稿ではないからです。
最後に、単にあなたのビューからヘルパーメソッドを呼び出します。
<%= sidebar_navigation_links %>
こんにちはJohnさん、あなたの答えをありがとうございます...しかし、私は問題があります.... 投稿を破棄した場合、私は連続したIDを失い、 Post.find_by_id(id - 1、:select => 'タイトル、スラッグなど...') 他の問題は、私はパーマリンクを持っていないと私はこの時点でIDで移動するが、 href => previous_post.permalink "by:" href => previous_post.id " href = emty :) 私を助けることができますか? もう一度ありがとう! – pollinoco
id + 1は存在しないがid + 2は問題を避けるため、次のようなモデル方法を使用しました。私の見解コードで
def previous
Post.where(["id < ?", id]).last
end
def next
Post.where(["id > ?", id]).first
end
、私はこれを行う:
- if @post.previous
= link_to "< Previous", @post.previous
- if @post.next
= link_to "Next >", @post.next
私の方法は、あなたが自動的にモデルのスコープを使用できるようになります。たとえば、「公開された」投稿のみを表示することができます。お使いのモデルで
:あなたのコントローラ
@photos = Photo.published.order('created_at')
関連RSpecのテストで
def self.next(post)
where('id < ?', post.id).last
end
def self.previous(post)
where('id > ?', post.id).first
end
あなたのビューで
<%= link_to 'Previous', @posts.previous(@post) %>
<%= link_to 'Next', @posts.next(@post) %>
:
describe '.next' do
it 'returns the next post in collection' do
fourth_post = create(:post)
third_post = create(:post)
second_post = create(:post)
first_post = create(:post)
expect(Post.next(second_post)).to eq third_post
end
it 'returns the next post in a scoped collection' do
third_post = create(:post)
decoy_post = create(:post, :published)
second_post = create(:post)
first_post = create(:post)
expect(Post.unpublished.next(second_post)).to eq third_post
end
end
describe '.previous' do
it 'returns the previous post in collection' do
fourth_post = create(:post)
third_post = create(:post)
second_post = create(:post)
first_post = create(:post)
expect(Post.previous(third_post)).to eq second_post
end
it 'returns the previous post in a scoped collection' do
third_post = create(:post)
second_post = create(:post)
decoy_post = create(:post, :published)
first_post = create(:post)
expect(Post.unpublished.previous(second_post)).to eq first_post
end
end
注:コレクションの最初/最後の投稿に行くと、小さな問題が発生します。前または次のボタンが存在する場合のみ条件付きで表示するためのビューヘルパーを推奨します。
私は特にこの種のタスクのために宝石proximal_records
を作成しました。これは、モデル内の動的に作成されたスコープで動作します。
https://github.com/dmitry/proximal_records
Basicの例:
class Article < ActiveRecord::Base
include ProximalRecords
end
scope = Article.title_like('proximal').order('created_at DESC, title ASC')
current_record = scope.to_a[5]
p, n = current_record.proximal_records(scope) # will find record 5 and 7
ありがとうございました!!!!完璧です! :) – pollinoco
@Sam、そう、私は "それぞれのタイトルが一意であるなら"と言ったのです。 – ryanb
申し訳ありませんRyan、私は盲目的になるはずです:条件=> ["title>?とid>?"、title、id]は回避する必要があります。タイトルにインデックスを追加することは、そのおもちゃのアプリがない限りここでは重要なことです。 –