Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have implemented follow/unfollow functionality and would like to add AJAX call to it, but I am stuck. My partial _follow_button.html.erb for follow/unfollow which is rendered on Users->index, looks like:

<% 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 %>

Then my controller for relationships looks like:

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

My view on user profile looks like:

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

My routes.rb have the following routes defined:

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

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

My Views folder structure has subfolders Users and Relationships. Both of them have separate controllers, and I have tried adding simple alert function 'alert("Works");' to the create.js.erb in both of those subfolders to try and match them with the controller, but none don't seem to work. This is my first Rails project, and I do not quite understand what the issue could be. Any suggestions?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
839 views
Welcome To Ask or Share your Answers For Others

1 Answer

Calling the partial follow/unfollow

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

Partial 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 for the partial. Ajax post to follow/unfollow

$('.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);
    }
  });

};

Changes in your controller.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...