Newbie-> help understanding "magic" behavior


#1

I am trying out ROR for the first time[1], and have much PHP poisoning
to overcome in my mental baggage. That said, I was delighted to find
that I could make a link from a “show” page to the next record in the
database by simply adding

@next_page = Content.find(params["id"].next)

to my content_controller.rb and then constructing a link to it within
my show.rhtml.

The only definition of the ‘next’ method I can find is within the
‘paginator’ class, yet I am not invoking that class as far as I can
tell. So there’s no problem with next per se, but trying to do the
opposite (in my mind, anyway) by setting

@prev_page = Content.find(params["id".previous  (and many, many other

attempts, like prev, or id -1, just to be utterly hacky)

Only gets me errors, and googling has so far not yielded the solution.

Any suggestions? Am I even trying to do this in the Right Place? The
book has been ordered, before you suggest that…

Thanks,

Walter

  1. Mac OS X 10.4.4, Locomotive 1.0.0, ruby 1.8.2 (2004-12-25)
    [powerpc-darwin7.9.0], MySQL 4.1.8-standard for apple-darwin7.6.0 on
    powerpc(Official MySQL-standard binary)

#2

The next method is actually a part of the Integer class. Fire up irb and
type
1.next
And behold! You get 2 :slight_smile: So, not a lot of magic, and not a
particularly
safe way to get to the next record (may not be a record 2) and so forth.
But
this is just on of the nice things about everything being an object in
Ruby.
You find a whole bunch of hidden treasures.

Also, if you fire up the rails console (from your rails-app path type
ruby script/console and then type
1.day.from_now

Hope this explains some of the mysteries!
-nick


#3

Thanks for the clue. I am now trying to use the Pagination module to
figure this out, but it’s not getting me much further. I can either get
a lovely syntax error, or a Next link to record 2 and a Previous link
to record null, but nothing meaningful.

Any further clues how I might show a single page (not a list)
representing a single record row, and then automagically get the next
and previous record ids, sorted by id?

Thanks in advance,

Walter


#4

Forgot to add – this is when I am starting from an id firmly in the
MIDDLE of the table.

Walter


#5

Thanks! I looked in the documentation, and this looks promising, but I
am having trouble implementing your example. What’s confusing me is
that you have defined a new view here with def next, right? Where would
you slot this code into an existing view:

def mypage
@title = Content.find(params[“id”])
end

Thanks again,

Walter


#6

I think you are getting confused on the use of the Paginator stuff. This
is
really meant to be used when you are display a big list of things. It
allows
to easily split a list of 100 objects into a list of 10 pages showing 10
objects each, and you can easily move back and forth between them.

It looks like, from what you’ve posted here you are displaying a single
object and then want to move to the next/previous, correct? If thats the
case, take a look at the “acts_as_list” method in the api. It will let
you
easily put actions in that would look something like:

def next
current = Object.find params[:id]
@prev = current.lower_item
end

and so on a so forth. Check it out, and see what you like.

Hope this helps!
-Nick


#7

Well, that gets rid of the previous error, but the links don’t show up
now either. If I get rid of the “if @content.higher_item” test, then I
get links that don’t work (they don’t have a record number following
them).

Walter


#8

Ok, so step through this. It looks like you want to display a “book”
style
site with pages, each with a possible next/prev page.

I would have my controller simply load the page, and have two links for
the
prev/next actions on the page itself. You could even ‘cheat’ and just
have
one page loading action:
controller stuff =>

def show_page
@page = Page.find params[:id]
end

view stuff =>

<%= link_to(“previous”, :id => @page.higher_item) if @page.higher_item
%>
<%= link_to(“next”, :id => @page.lower_item) if @page.lower_item %>

(might need to play with the method calls a little a bit to make sense
for
you, the wording for acts_as_list is a bit weird in this case)

Let me know if I’ve assumed anything wrong here!

-Nick


#9

Yes, that’s part of the contract for acts_as_list, it needs a position
column. Also, setting the position to be the id is a bad idea. what
happens when you want to possibly move a page? or insert a new page in
between other pages?

Glad you got it working!
-Nick


#10

Sorry, I just realized that this works perfectly as long as you add a
column named position, and critical, missing step here populate that
column with the contents of the id column.

I had tried just setting the position column to BE the id column in my
controller, but that failed for some reason. I’ll have to go back and
try again to be sure.

Thanks for the wonderful help.

Walter