I'm trying to build something that will randomly pick two objects from a list in Ruby (using Rails) and then perform basic operations on those objects. My current set up involves randomly picking numbers at the start - using these numbers to get objects from the database and then rendering those objects to index. However, now I'm trying to edit these objects using AJAX I'm running into a problem.
It seems that, when I click on a link that the random number in being recalculated and is causing my AJAX function not to work.
I've included (what I believe is) all relevant code below but let me know if you need to see anything else to get to the bottom of this. I'm looking to get the titles of the old animals and (ideally their previous ratings and) their new ratings to appear at the bottom of the page.
Thanks,
Matt
controllers/static_pages.rb
class StaticPagesController < ApplicationController
respond_to :html, :js
before_filter :pickanimals
def pickanimals
@allAnimals = Animal.all
@random_no = rand(@allAnimals.length)
@animal = @allAnimals[@random_no]
@allAnimals.delete_at(@random_no)
@newRandom = rand(@allAnimals.length)
@animal2 = @allAnimals[@newRandom]
end
def index
respond_to do |format|
format.html
format.js
end
end
def help
end
def about
end
def contact
end
def league
end
def voting
@votedAnimal = Animal.find(params[:id])
if @votedAnimal == @animal
@animal.rating += 1
@animal2.rating -= 1
else
@animal.rating -= 1
@animal2.rating += 1
end
Animal.transaction do
@animal.save!
@animal2.save!
end
respond_to do |format|
format.html { redirect_to root_path }
format.js
end
end
end
app/views/static_pages/index.html.erb
<div class="center hero-unit">
<h1>Animal Attack</h1>
<p> Who will win when nature collides? </p>
<div class="animalcontainerright">
<h2> <%= @animal.name %> </h2>
<%= link_to image_tag(@animal.attachment.url(:large)), voting_path(@animal.id), :remote => true, :confirm => "Rating: "[email protected]_s %>
</div>
<div class="animalcontainerleft">
<h2> <%= @animal2.name %> </h2>
<%= link_to image_tag(@animal2.attachment.url(:large)), voting_path(@animal2.id), :remote => true, :confirm => "Rating: "[email protected]_s %>
</div>
<div id="animalfacts"></div>
routes.rb
AnimalAttack::Application.routes.draw do
resources :animals
root to: 'static_pages#index'
match '/help' => 'static_pages#help'
match '/about' => 'static_pages#about'
match '/contact' => 'static_pages#contact'
match '/league' => 'static_pages#league'
match '/voting/:id' => 'static_pages#voting'
end
rake routes
animals GET /animals(.:format) animals#index
POST /animals(.:format) animals#create
new_animal GET /animals/new(.:format) animals#new
edit_animal GET /animals/:id/edit(.:format) animals#edit
animal GET /animals/:id(.:format) animals#show
PUT /animals/:id(.:format) animals#update
DELETE /animals/:id(.:format) animals#destroy
root / static_pages#index
help /help(.:format) static_pages#help
about /about(.:format) static_pages#about
contact /contact(.:format) static_pages#contact
league /league(.:format) static_pages#league
/animals(.:format) animals#new
/voting/:id(.:format) static_pages#voting
I'm guessing @animal
is being re-assigned because of your :before_filter
. Unless you tell it otherwise, it'll execute before all actions (thus reassigning @animal
before every controller action). You probably want to limit it to just the methods that need a newly-regenerated random number. For example:
before_filter :pickanimals, :only => :index
Also. Do you know about Array#sample? It's a built-in way of picking a random element from an array. You might find it useful here:
@animal, @animal2 = @allAnimals.sample(2)
ADDITIONALLY
Relying on instance variables in the controller like this is a pretty fragile way of passing information between functions. If your controller needs to know the id
s of two models to have counters on each incremented or decremented based on user selection, why not just use a form to send those two id
s to this controller action? So far, you'll only need two fields: chosen_animal_id
and reject_animal_id
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With