1

I've been working with Rails for a couple of years, but this is my first attempt at AJAX and Javascript. I spent a huge amount of time reading various web sites, trying to figuring out what goes where & what it's supposed to do.

I'm trying to make the 'refreshme' div in edit.html.erb in a Rails 4 app refresh every time the 'turn' field in the 'stories' table changes. So I wrote a setInterval() function in story.js to check @story.turn & refresh. I can get it to refresh every 10s, but I only want the code to check the value of story.turn every 10s, & refresh only if the value has changed.

routes.rb (Is this right?)

match '/stories/:id/refresh' => "stories#refresh", :as => :story_refresh, via: 'post'

refresh.html.erb (in views/stories - I have no clue what belongs here)

<div class="pollme" data-story-id="<%=@story.id %>" data-story-turn="<%=@story.turn %>" > 
  <%=@story.turn %> // This gets changed based on what other users are editing
</div>

edit.html.erb (views/stories) - show.html.erb refreshes nicely into this div

<div class="refreshme" data-story-id="<%=@story.id %>" data-story-turn="<%=@story.turn %>" >
  <%= render 'shared/micropost_form' %>
</div>

story.js

$(document).on("page:change", function() {
  var $turn;
  $turn = $('.refreshme').data('story-turn'); 

  refreshStories = function(){

    $.ajax({     
        type: "POST",
        data: {  },  // I'm sure something important goes here to get @story.turn out of the stories table
        url: "/stories/"+$('.refreshme').data('story-id')+"/refresh"    
    }).done(function(result) {
            alert('done' );
        $turn = ; // Not sure what data{} can return
    })

    if ($('.refreshme').data('story-turn') != $turn) {
      $.ajax({
        type: "GET", // helps show.html.erb get refreshed into refreshme div in edit.html.erb
        url: "/stories/"+$('.refreshme').data('story-id') 
      }).done(function(result) {
        var $sentence_requests = $('.refreshme');
        if ($sentence_requests.length > 0) {
            $sentence_requests.html(result);
            alert('UPDATED micropost requests ') ;
        } else {
        }
      })
    }
  };
  setInterval(refreshStories, 10000); 
});  

stories_controller.rb

def refresh
  @story = Story.find(params[:id])
  respond_to do |format|
    format.json { }  
    format.html { }
  end  
end

def edit
  @story = Story.find(params[:id])
  @micropost  = @story.microposts.build
  respond_to do |format|
    format.json { } 
    format.html { }
  end  
end

In story.js, the GET function executes, however the POST function does not. I'm not sure what I'm supposed to 'POST' (I thought I was 'GETting' a value from the database, but I guess not).

I think POST is the AJAX function I need to obtain @story.turn from the stories table, but don't know how to make it do anything. Do I also need GET to refresh? I've been kludging this code for weeks now, this seems like something I should've figured out by now. Any help would be greatly appreciated.

ThinQtv
  • 103
  • 1
  • 1
  • 11

1 Answers1

0

If you put this on a public github repo, people could see your code in-context, and also send a pull request demonstrating how they'd do it.

  • OK, Joe, here's my repo. https://github.com/crowdpublishtv/sentenceZing I edited it a bit because I was trying RailsCast 229, but that doesn't really do what I want. I need to update @story.turn so the micropost textbox will get displayed after a story partner enters their story micropost. See http://sentenceZing.com for implementation. – ThinQtv May 21 '14 at 23:15
  • I tried to take a look, but the project is in a broken state: rake db:migrate fails on a clean install: – Joe Grossberg May 22 '14 at 15:29
  • I tried to take a look, but the project is in a broken state: rake db:migrate fails on a clean install: SQLite3::SQLException: no such table: likes: ALTER TABLE "likes" ADD "user_id" integer I'm not gonna spend more time on this, but my main question is: why do you believe you need a POST? All you need is an AJAX GET that hits an endpoint. Have that endpoint query the DB and return a response that gives you enough info to say "this value did [not] change". Then, act accordingly based on that response. No need for a POST, which implies you're changing data on the server. – Joe Grossberg May 22 '14 at 15:37
  • Also this [Angular question](http://stackoverflow.com/questions/11276520/can-angular-js-auto-update-a-view-if-a-persistent-model-server-database-is-cha) is relevant. – Joe Grossberg May 22 '14 at 15:38
  • I know it doesn't answer your question, but hopefully that enough to get you un-stuck. – Joe Grossberg May 22 '14 at 16:45
  • I somehow solved most of this on my own. The db:migrate problem is because there was a table dropped then added & db:migrate doesn't know how to deal with that. I found some stuff in RailsCast 229 that isn't close to what I ended up doing, but gave me hints for how to kludge a solution together. – ThinQtv May 23 '14 at 00:56
  • Yeah, POST did nothing for me. I had seen it in a PHP example and thought it was similar. I ended up creating an index.js.erb file to get my value from the database, then executed an AJAX GET from index.js.erb. – ThinQtv May 23 '14 at 00:58