2016-09-14 4 views
0

Ich versuche, wieder in Ruby zu gelangen, und erstellen eine einfache Abstimmung nach oben und unten (wie Reddit).Verwenden von Ajax mit Ruby

Ich kann die Stimmen erhalten, um zu arbeiten, aber die Seite wird jedes Mal neu geladen. Ich versuche einen Ajax-Aufruf zu implementieren, um die Werte dynamisch zu ändern, aber die einzigen Anleitungen, die ich finden kann, sind für Rails. Ich benutze Ruby nur mit einem Sinatra-Server.

die html.erb

<form action="/votes" method="post"> 
    <input type="hidden" name="post_id" value="<%= post.id %>"> 
    <button id="thumb-up"><img src="/images/thumbs-up.gif" /></button> 
    </form> 
    <p> <%= post.votes.count %> </p> 
    <form action="/votes" method="post"> 
    <input type="hidden" name="_method" value="delete"> 
    <input type="hidden" name="post_id" value="<%= post.id %>"> 
    <button id="thumb-down"><img src="/images/thumbs-down.gif" /></button> 
    </form> 

jquery

$('#thumb-up').on('click', function(e) { 
    e.preventDefault(); 

$.ajax({ 
    url: '/votes', 
    method: 'post', 
    success: function() { 
     console.log('vote up'); 
     $(this).html("<%= post.votes.count %>"); 
    } 
    }) 
}); 

und das Modell

class Vote < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :post 

    validates :post, uniqueness: { scope: :user } 
    validates :user, uniqueness: { scope: :post } 

end 

Die Routen (sorry, später hinzugefügt)

post '/votes' do 
    if logged_in? 
    vote = Vote.new 
    vote.user_id = current_user.id 
    vote.post_id = params[:post_id] 
    vote.save 
    redirect to '/' 
    else 
    redirect to '/session/new' 
    end 
end 

delete '/votes' do 
    if logged_in? 
    votes = Vote.where(user_id: current_user.id, post_id: params[:post_id]) 

    votes.each do |vote| 
     vote.delete 
    end 
    redirect to '/' 
    else 
    redirect to '/session/new' 
    end 
end 

Jetzt vermute ich, das ist eine super einfache Sache, und ich weiß, dass Remote: True hat etwas damit zu tun.

Im Moment bekomme ich einen 500 Fehler mit dem Daumen-hoch-Knopf, aber nicht mit dem Daumen-nach unten, der url: 'delete' statt post hat.

Kann ich dies ohne ein Formular für jede Schaltfläche erreichen?

+1

Hinweis: Studieren Sie einige anfängliche Ajax-Tutorials und versuchen Sie eine zu finden, bei der die Syntax '<% = post.votes.count%>' eingeführt wird. – 7stud

+0

'remote: true' ist eine Rails-Convenience-Sache, die Ajax für Sie erledigt. Sinatra hat nichts Vergleichbares. Meist geht es dir gut, mit kleinen Fehlern (teilweise konzeptionell). '500' bedeutet Fehler in Ihrem Servercode - und Sie haben Ihre Sinatra-Routen nicht gepostet, daher können wir nichts dazu sagen. Wie @ 7stud sagt, sollte Ihr '$ (this) .html' wahrscheinlich etwas übergeben, das in Ajax-Antwort war, und nicht etwas, das vorher gerendert wurde (oder schlimmer noch, nicht gerendert). – Amadan

+0

* Kann ich dies ohne ein Formular für jede Schaltfläche erreichen? * Ja. Eine Schaltfläche benötigt kein Formular, um auf einer HTML-Seite zu existieren. Und eine Schaltfläche kann angeklickt werden, ohne dass ein Formular auf der Seite vorhanden ist. Aber Sie müssen in der Lage sein, Code zu verwenden, um zu identifizieren, auf welche Schaltfläche geklickt wurde, z. Überprüfen Sie seine ID, damit Sie dem Server mitteilen können, was Sie in Ihrer Ajax-Anfrage tun sollen. – 7stud

Antwort

-1

ich auf gleiche Sache gearbeitet hatte, ist es einfach, wenn u wie dieses

<%= link_to image_tag(likepic), like_post_path(post,status: true), class: 'vote', method: :put, remote: true %> 

like_user_path nennen ajax geht "wie" Methode in der Post-Controller und Beiträge Status: true Mittel

"gemocht"

Hoffnung es funktioniert, weil es für mich

und das Modell

class Like < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :post 
end 
+0

Er verwendet keine Schienen, daher ist 'like_post_path' nicht zugänglich. Sowie 'remote: true' –

+0

oh sorry, ich sehe nicht – Bee

0

arbeitete I hier denken, der Fehler ist:

validates :post, uniqueness: { scope: :user } 

und hier

$.ajax({ 
    url: '/votes', 
    method: 'post', 
    success: function() { 
     console.log('vote up'); 
     $(this).html("<%= post.votes.count %>"); 
    } 
    }) 

Ihre Stimme erfordert eine Post-ID, aber Sie nicht in Ihrer Ajax-Anforderung senden.