2013-03-22 22 views
10

Jestem nowym do szyn i próbuje zmienić wartość logiczną za pomocą wyboru i za pomocą jquery ajax:Szyny zmienić wartość logiczną z wyboru i jquery ajax

<%- @tasks.each do |task| %> 
    <div class="task-wrapper"> 
    <%= check_box_tag 'completed', task.id , task.completed, :class => "task-check" %> 
    <%= content_tag :span, task.task %> 
    <%= content_tag :span, task.deadline %> 
    </div> 
<% end %> 

i javascript:

$(".task-check").bind('change', function(){ 
    if (this.checked){ 
    var bool = this.checked ? 1 : 0; 
    $.ajax({ 
     url: '/todos/toggle', 
     type: 'POST', 
     data: '{"task_id":"'+ this.value +'", "bool":"'+ bool +'"}' 
    }); 
    } 
    else { 
    alert("no"); 
    } 
}); 

wówczas regulator:

def toggle(task_id, bool) 
    @task = Todo.find_by_id(task_id) 

    if @task != nil? 
    @task.update_attributes(:completed => bool) 
    else 
    set_flash "Error, please try again" 
    end 
end 

końcu trasy:

resources :todos do 
    member do 
    post 'toggle' 
    end 
end 

również wypróbowany kolekcji, ale daje ten sam błąd.

kiedy kiedykolwiek spróbuję, otrzymam od akcji 404 error.

na czym polega problem?

dzięki

+0

Czy twoja pętla zadań znajduje się wewnątrz formularza? – Catfish

+0

@Catfish - nie ma poza formularzem – Wahtever

+1

Dlaczego nie umieścić go w formularzu? To byłoby o wiele prostsze. Wtedy zamiast 'check_box_tag' możesz użyć' f.check_box'. – Catfish

Odpowiedz

14

Spróbuj (wszystko inne pozostawiając jak jest) następujące:

javascript:

$(".task-check").bind('change', function(){ 
    if (this.checked){ 
    $.ajax({ 
     url: '/todos/'+this.value+'/toggle', 
     type: 'POST', 
     data: {"completed": this.checked} 
    }); 
    } 
    else { 
    alert("no"); 
    } 
}); 

kontroler:

def toggle 
    @task = Todo.find(params[:id]) 

    if @task.update_attributes(:completed => params[:completed]) 
    # ... update successful 
    else 
    # ... update failed 
    end 
end 

Spójrz na bundle exec rake routes do pokazać ścieżki, które generuje szyny. W przypadku Twojego post 'toggle', który jest członkiem, otrzymujesz ścieżkę taką jak /todos/:id/toggle, stąd zaktualizowany URL w ajax.

W kontrolerze :id ze ścieżki kończy się params[:id]. Dane z żądania ajax również kończą się na mieszaniu params, a więc params[:completed].

+0

Działa to świetnie, czy mógłbyś wyjaśnić, dlaczego tak się dzieje? Dzięki – Wahtever

+1

Dodano pewne wyjaśnienie, krzyczeć, jeśli coś jest niejasne. – ramblex

+1

Należy pamiętać, że Rails 4 dodaje prostszy sposób, jak wspomniano poniżej. –

19

Jak Rails 4, istnieje sposób, aby to zrobić bez konieczności ponoszenia dodatkowych JS lub CSS:

<%= check_box_tag 'completed', task.id, task.completed, 
     data: { 
     remote: true, 
     url: url_for(action: :toggle, id: task.id), 
     method: "POST" 
     } %> 

Okazuje się, że dodanie remote: true do wejścia powoduje jQuery ujs aby ajax-rw wszystkie miłe sposoby. Thoughtbot's "A Tour of Rails jQuery UJS" krótko dotyka tego (i wielu innych dobrych rzeczy dostępnych); the "Unobtrusive scripting support for jQuery" page w wiki jQuery UJS również zajmuje się tą sprawą.

+0

Dostępne również dla wcześniejszych wersji szyn, nie do końca pewne, które z nich, ale ostatnia wersja 3 działa. – dft