使用ajax在rails中渲染跟随/取消关注按钮

时间:2018-02-11 19:51:42

标签: javascript jquery ruby-on-rails ruby ajax

我已经实现了follow / unfollow功能,并希望为它添加AJAX调用,但我被卡住了。 我的部分_follow_button.html.erb用于follow / unfollow,它在Users-> index上呈现,如下所示:

<% if current_user.id != user.id %>    

    <% if !current_user.following?(user) %>
        <%= form_for(current_user.active_relationships.build, remote: true) do |f| %>
            <div><%= hidden_field_tag :followed_id, user.id %></div>
            <span class="follow"><%= f.submit "Follow User", class: "btn btn-primary btn-sm" %></span>
        <% end %>
    <% else %>
        <%= form_for(current_user.active_relationships.find_by(followed_id: user.id),
                        html: { method: :delete }, remote: true) do |f| %>
            <span class="unfollow"><%= f.submit "Unfollow User", class: "btn btn-secondary btn-sm" %></span>
        <% end %>
    <% end %>

<% end %>

然后我的关系控制器看起来像:

class RelationshipsController < ApplicationController

  respond_to :js, :json, :html
  def create
        user = User.find(params[:followed_id])
       @follow = current_user.follow(user)
  end

  def destroy
        user = Relationship.find(params[:id]).followed 
        @unfollow = current_user.unfollow(user)
  end

end

我对用户个人资料的看法如下:

<div class="col-5" style="margin-left: -5px;">
    <%= render '/components/follow_button', :user => User.find_by_username(params[:id]) %>
</div>

我的routes.rb定义了以下路线:

resources :users do
    member do
      get :following, :followers
    end
  end

  resources :relationships, only: [:create, :destroy]

我的视图文件夹结构包含用户和关系的子文件夹。它们都有独立的控制器,我尝试添加简单的警报功能&#39;警告(&#34; Works&#34;);&#39;到这两个子文件夹中的create.js.erb尝试将它们与控制器匹配,但似乎没有一个工作。这是我的第一个Rails项目,我不太明白这个问题是什么。有什么建议吗?

2 个答案:

答案 0 :(得分:0)

调用部分关注/取消关注

<% if current_user.id != user.id %>
  <%= render partial: 'follow_links', locals: { user: user }
<% end %>

部分follow_links。

<% show_follow_link   = current_user.following?(user) ? 'hidden' : '' %>
<% show_unfollow_link = current_user.following?(user) ? '' : 'hidden' %>

<!-- links to follow/unfollow have data-attributes that include the path to make the ajax post and the user to follow, that is used to find the link to show after the ajax call. You should use the path to the controller that will create or destroy the relationship -->
<%= link_to 'Follow',   '#', { class: 'follow-user btn-success #{show_follow_link}', "data-url": follow_user_path(user.id), "data-followee": user.id } %>
<%= link_to 'Unfollow', '#', { class: 'unfollow-user btn-danger #{show_unfollow_link}', "data-url": unfollow_user_path(user.id), "data-followee": user.id } %>

部分的Javascript。关注/取消关注的Ajax帖子

$('.follow-user').on("click",function() {
  follow_unfollow($(this), "follow")
});

$('.unfollow-user').on("click",function() {
  follow_unfollow($(this), "unfollow")
});

function follow_unfollow(target, what_to_do)
  url = target.attr('data-url')
  followee = target.attr('data-followee')
  if (what_to_do == "follow") {
    other_button = $('.unfollow-user[data-followee="'+followee+'"]')
  } else {
    other_button = $('.follow-user[data-followee="'+followee+'"]')
  }

  $.ajax( {
    url: url,
    type: 'post',
    success: function() {
      // Hide this link
      target.addClass('hidden');
      // Show the other link
      other_button.removeClass('hidden');
    },
    error: function(ret) {
      alert(ret.responseJSON.error);
    }
  });

};

您的控制器发生了变化。

class RelationshipsController < ApplicationController
  def create
    user = User.find(params[:followed_id])
    @follow = current_user.follow(user)

    respond_to do |format| 
      if @follow.valid?
        format.html
        format.json: { render json: @follow }
        return
      else
        format.html
        format.json: { render json: { :error => 'Follow failed', :status_code :not_found } }
      end
    end
  end

  def destroy
    user = Relationship.find(params[:id]).followed 
    @unfollow = current_user.unfollow(user)

    respond_to do |format| 
      if @unfollow.valid?
        format.html
        format.json: { render json: @unfollow }
      else
        format.html
        format.json: { render json: { :error => 'Unfollow failed', :status_code :not_found } }
      end
    end
  end
end

答案 1 :(得分:0)

建议

关于你上一次question的建议:我建议 - 而不是在StackOverflow上发布有关调试代码的问题 - 为自己创建一个良好的调试环境

ByebugBinding pry是一个很好的起点,但在您正确使用它们之前,您需要了解您正在使用的代码。我建议深入阅读Working with Javascript! - 它确实帮助我掌握了它并理解了Rails和ajax的数据流。

我认为,这会破坏牢不可破的Stackoverflow循环,我自己被绑了很长时间了:

loop do
  puts "Try code"
  sleep 1000
  puts "Arrhh! an error!"
  sleep 1000
  puts "Posting on Stackoverflow"
  sleep 1000
  puts "Waiting for answer"
  sleep 1000
end 

我希望你弄明白!