Timothy Hunkele
Timothy Hunkele

Reputation: 887

Rails Remote Link Processing as JS then HTML

I have a link marked :remote => true that makes a get request to Controller#show as JS and is rendered in the browser. After this request completes another get request for Controller#show as HTML is processed.

While debugging I wrapped the show action contents in if request.xhr? && !request.format.html?

The first Controller#show as js request showed correctly in the browser and the unintended rendering of Controller#show as HTML failed and nothing made it to the browser obviously.

My question is, has anybody experienced this subsequent html call after a js call? I can't find anything in my code causing this.

Link code

= link_to article.name, blog_path(article.name.downcase.gsub(' ','-')), :remote => true

Controller code

  def show
      article_name = params[:id].gsub('-',' ')

      @article = Article.find_by_name(article_name)

    respond_to do |format|
      format.html # show.html.erb
      format.js
      format.xml  { render :xml => @article }
    end
end

show.js.haml code

$('#content_index.blog').html("#{escape_javascript(render('article'))}");

_article.html.haml code

.blog_post
  %h2
    = @article.name
  %img{:src => "#"}/
  .blog_text
    %p
      = @article.content
%center
  .blog_post_bottom
    #next.blogbuttons next
    #previous.blogbuttons previous
    %p
      posted on
      = link_to @article.created_at.to_s(:date_only), "#"
      in
      %a{:href => "#"} CS at work
      by
      = link_to @article.author_name, "#"

routes.rb code

  resources :articles, :only => [:index, :show]
  resources :blog, :controller => :articles

Log output from single js request (also happens for html request with javascript in the browser disabled)

Started GET "/blog" for 127.0.0.1 at Thu Nov 03 14:38:29 -0400 2011
  Processing by ArticlesController#index as JS
  Article Load (9.3ms)  SELECT `articles`.* FROM `articles` 
Rendered articles/_articles.html.haml (2.3ms)
Rendered articles/index.js.haml (2.8ms)
Completed 200 OK in 20ms (Views: 3.5ms | ActiveRecord: 9.3ms)


Started GET "/blog" for 127.0.0.1 at Thu Nov 03 14:38:30 -0400 2011
  Processing by ArticlesController#index as HTML
  Article Load (9.7ms)  SELECT `articles`.* FROM `articles` 
Rendered articles/index.html.haml within layouts/application (2.7ms)
Rendered user_sessions/_new.html.haml (2.5ms)
Rendered shared/_header.html.haml (3.9ms)
Rendered shared/_footer.html.haml (0.8ms)
Completed 200 OK in 26ms (Views: 9.1ms | ActiveRecord: 9.7ms)

Upvotes: 4

Views: 3004

Answers (2)

Timothy Hunkele
Timothy Hunkele

Reputation: 887

Turns out that %img{:src => "#"}/ was causing the page to render multiple times. I removed this line and everything worked as it's supposed. If you need to use an image place holder use = image_tag "" this will cause a routing error but that's much better than the page rendering multiple times.

Upvotes: 1

Jon Dean
Jon Dean

Reputation: 215

If you are using Rails 3+ you should instead put respond_to :html, :json, :xml at the top of your controller and then inside the show action use respond_with @article. So it might look like:

respond_to :html, :json, :xml

def show
  article_name = params[:id].gsub('-', ' ')
  @article = Article.find_by_name(article_name)
  respond_with(@article)
end

It's much cleaner and easier to maintain.

I'd also suggest you look at the documentation for to_param (http://apidock.com/rails/ActiveRecord/Base/to_param) instead of the gsub code you have in there to find an article by it's name rather than ID.

If that doesn't help I'll have to take a closer look later after work where I can actually throw some code in a test app and debug.

Upvotes: 0

Related Questions