user3763074
user3763074

Reputation: 353

Accessing the next record in the associated collection

I am new to Rails, trying to write a simple flashcard program where a user has a deck of vocabulary cards they are cycling through...

The model is a very straightforward relationship between user and card where:

 User  has_many :cards
 Card  belongs_to :user

The basic gist is that a user views a card on the index page and clicks a button, "flipping" over to the show page, where the other side is displayed.

Have created and seeded my AR database, currently rendering a functional version that accesses and "flips" card #1 in my deck, but am stuck up on accessing the second, third, fourth cards, etc.

I have tried many different variations on AR queries in my Card controller to get the next cards in the deck but none have worked... here's what I've got in my card controller now:

 def index
    @card = Card.all.next
    @cards = Card.all
  end
`

Here's my card model:

class Card < ActiveRecord::Base
  belongs_to :user

  def self.next
    n = 1 
    if self.id != Card.all.first.id
      Card.all.find_by(id: Card.all.first.id + n)
    end
    n += 1
  end

  validates :word_text, presence: true
  validates :meaning_text, presence: true
end

Here's my rake routes:

  Prefix Verb   URI Pattern                    Controller#Action
     root GET    /                              cards#index
    cards GET    /cards(.:format)               cards#index
         POST    /cards(.:format)               cards#create
 new_card GET    /cards/new(.:format)           cards#new
edit_card GET    /cards/:id/edit(.:format)      cards#edit
     card GET    /cards/:id(.:format)           cards#show
        PATCH    /cards/:id(.:format)           cards#update
          PUT    /cards/:id(.:format)           cards#update
       DELETE    /cards/:id(.:format)           cards#destroy
          GET    /cards/:id(.:format)           cards#show
`

..... So, because of the above, the code below is of course not doing what i want it to do, but here's my view page as of now:

<div id="front_page_container" class="medium-8 medium-centered text-center columns">

  <div class="row">
  </div>
</div>

<div id="box-container">

    <br> <br> <%= button_tag(type: 'button') do %>

    <h1 style="color:yellow"> <%= @card.word_text %>    

    <ul><%= link_to 'Tap to flip card', card_path(@card) %></ul>  
    <ul> <%= content_tag(:strong,'Tap to flip the card') %> </ul>

    <% end %></h1>

</div>

<br> <br> <%= button_tag(type: 'button') do %>

    <ul><%= link_to 'New Card', cards_path(@next) %></ul>  

    <ul> <%= content_tag(:strong,'New Card') %> </ul>

<% end %>

To be honest, I am very stuck on how to create a path from my index page (which is displaying card #1, or @card) BACK to a new index page where card #2, or @next, is displayed instead... any help would be much appreciated!

Upvotes: 3

Views: 160

Answers (1)

Marc
Marc

Reputation: 448

Get the @next card by doing the following

@card = Card.find(params[:id])
@next = Card.where('id > ?', @card.id).first
@next = Card.first if @next.nil?

Remeber that when @card is the last card in your DB, you will want to handle that as well since @next would be nil in that case, which is the reason for the third line.

Edit: To fix your specific code, you need to modify your next method in your model like this

def next  # This is a method on an INSTANCE of Card, not the Class
  next_card = Card.where('id > ?', self.id).first
  next_card = Card.first if next_card.blank?
  next_card
end

This method is then called on @card, not Card, so something like this

<%= link_to 'New Card', card_path(@card.next) %>

Upvotes: 2

Related Questions