1

我不确定这里有什么问题要知道我到底在问什么,但我会尽力而为。我试图在我认为问题所在的地方加粗以使其更清楚。

我是第一次使用 ajax。在应用程序中,用户 (1) 搜索用户 (2),找到用户 (2) 后,用户 (1) 可以单击“添加关系”按钮,该按钮向用户 (2) 发送关系请求。“添加关系”按钮应立即更改为“请求的关系”,然后在刷新页面后,该按钮应更改为“编辑关系”。

'添加关系' = 尚不存在关系 '请求关系' = 存在待处理关系,就像一条成功消息'编辑关系' = 存在待处理关系或存在已接受的关系

除了在刷新浏览器页面时按钮应更改为“编辑关系”的最后一部分之外,一切正常。出现“添加关系”

这个“编辑关系”按钮不会出现的任何想法?我正在使用状态机、draper 和 js-routes gem。

查看/用户/索引:

在搜索用户(2)时,他们的名字出现在名字旁边,“添加关系”、“编辑关系”或“请求关系”按钮出现

我认为这里的 if 语句是行不通的。为什么它不根据它是挂起还是接受来查找关系?

<% if logged_in? %>
    <ul>
        <% @users.each do |user| %>
            <li>
                <%= user.name %>
                <div id="relationship-status">
                    <% if current_user.following.include?(user.id) || current_user.pending_following.include?(user.id) %>
                        <%= link_to "Edit Relationship", edit_relationship_path(followed_id: user.id), class: "btn btn-primary" %>
                    <% else %>
                        <%= link_to "Add Relationship", new_relationship_path(followed_id: user.id), class: "btn btn-primary", id: 'add-relationship', data: { followed_id: user.id.to_param } %>
                    <% end %>
                </div>
            </li>
        <% end %>
    </ul>
<% end %>   

控制器/用户:

  def index
    @users = User.search(params[:search])
  end

关系.js:

$(document).ready(function() {

    $('#add-relationship').click(function(event) {
        event.preventDefault();
        var addRelationshipBtn = $(this);
        $.ajax({
            url: Routes.relationships_path({relationship: { followed_id: addRelationshipBtn.data('followedId') }}),
            dataType: 'json', 
            type: 'POST', 
            success: function(e) {
                addRelationshipBtn.hide();
                $('#relationship-status').html("<a href='#' class='btn btn-success'>Relationship Requested</a>");
            }
        });
    });
});

型号/用户:

class User < ActiveRecord::Base
  has_one :profile, dependent: :destroy
  has_many :pending_relationships,  class_name:  "Relationship",
                                    foreign_key: "follower_id"
  has_many :active_relationships,   class_name:  "Relationship",
                                    foreign_key: "follower_id",
                                    dependent:   :destroy
  has_many :passive_relationships,  class_name:  "Relationship",
                                    foreign_key: "followed_id",
                                    dependent:   :destroy                                
  has_many :following, -> { where(relationships: { state: "accepted" } ) }, through: :active_relationships,  source: :followed
  has_many :followers, through: :passive_relationships, source: :follower                              
  has_many :pending_following, -> { where(relationships: { state: "pending" } ) }, through: :pending_relationships,  source: :followed

关系/装饰者:

class RelationshipDecorator < Draper::Decorator
  delegate_all

  decorates :relationship

  def relationship_state
    model.state.titleize
  end

  def sub_message
    case model.state
    when 'pending'
      "Relationship request pending"
    when 'accepted'
      "You are now connected with #{model.followed.name}"
    end
  end
end

编辑:

分贝/迁移:

class AddStateToRelationships < ActiveRecord::Migration
  def change
    add_column :relationships, :state, :string
    add_index :relationships, :state
  end
end

型号/关系:

class Relationship < ActiveRecord::Base
  belongs_to :follower, class_name: "User"
  belongs_to :followed, class_name: "User"
  validates :follower_id, presence: true
  validates :followed_id, presence: true

  after_destroy :delete_mutual_relationship!

  state_machine :state, initial: :pending do
    after_transition on: :accept, do: [:send_acceptance_email, :accept_mutual_relationship!]

    state :requested

    event :accept do
      transition any => :accepted
    end
  end

终端输出:

Started POST "/relationships?relationship%5Bfollowed_id%5D=25" for 127.0.0.1 at 2014-11-06 16:35:26 +1100
Processing by RelationshipsController#create as JSON
  Parameters: {"relationship"=>{"followed_id"=>"25"}}
  User Load (0.4ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 1 LIMIT 1
  User Load (0.3ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = ? LIMIT 1  [["id", 25]]
   (0.1ms)  begin transaction
  SQL (5.4ms)  INSERT INTO "relationships" ("created_at", "followed_id", "follower_id", "state", "updated_at") VALUES (?, ?, ?, ?, ?)  [["created_at", "2014-11-06 05:35:26.360104"], ["followed_id", 25], ["follower_id", 1], ["state", "pending"], ["updated_at", "2014-11-06 05:35:26.360104"]]
  SQL (0.2ms)  INSERT INTO "relationships" ("created_at", "followed_id", "follower_id", "state", "updated_at") VALUES (?, ?, ?, ?, ?)  [["created_at", "2014-11-06 05:35:26.368921"], ["followed_id", 1], ["follower_id", 25], ["state", "requested"], ["updated_at", "2014-11-06 05:35:26.368921"]]
  Relationship Load (0.1ms)  SELECT  "relationships".* FROM "relationships"  WHERE "relationships"."id" = ? LIMIT 1  [["id", 49]]
  User Load (0.1ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = ? LIMIT 1  [["id", 1]]
  User Load (0.1ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = ? LIMIT 1  [["id", 25]]
  Rendered user_mailer/relationship_requested.html.erb (0.2ms)

UserMailer#relationship_requested: processed outbound mail in 27.9ms

Sent mail to example-24@example.com (14.2ms)
Date: Thu, 06 Nov 2014 16:35:26 +1100
From: noreply@example.com
To: example-24@example.com
Message-ID: <545b089e6206e_6c313ff72cf9cf78434189f@example.local.mail>
Subject: Firstname Surname wants to follow you. Please log in to accept
 this request
Mime-Version: 1.0
Content-Type: text/html;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

Hi example-24, 

Firstname Surname wants to follow you.

   (7.7ms)  commit transaction
Completed 200 OK in 71ms (Views: 0.3ms | ActiveRecord: 14.4ms)

当我(用户 1)搜索用户 example-24(用户 id = 25)然后按“添加关系”按钮时会发生什么(如 sqlitebrowser 所示:(请参阅图像底部与此相关的 2 行例子)

数据库关系表

编辑:

用户/控制器:

  def create
    if params[:relationship] && params[:relationship].has_key?(:followed_id)
      @followed = User.find(params[:relationship][:followed_id])
      # @followed = User.where(name: params[:relationship][:followed_id]).first
      @relationship = Relationship.request(current_user, @followed)
      respond_to do |format|
        if @relationship.new_record?
          format.html do
            flash[:danger] = "There was a problem creating that relationship request"
            redirect_to followed_path(@followed)
          end
          format.json { render json: @relationship.to_json, status: :precondition_failed }
        else
          format.html do
            flash[:success] = "Friend request sent"
            redirect_to followed_path(@followed)
          end
          format.json { render json: @relationship.to_json }
        end
      end
    else
      flash[:danger] = "Friend Required"
      redirect_to users_path
    end
  end
4

1 回答 1

1

虽然我无法修复你的这个错误,但你可以这样做。

  1. 有一个form_forlink_to带有一个选项remote true。
  2. Acontroller和 aroute回应你的action

例如:

在你的routes.rb

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

在你的关系中_controller.rb

def create
  //find the user_id of the to_be_followed user
  // like User.find(params[:relationship][:user_id] 
  // this :relationship comes from your controller
  // and current_user.relationsihps.create(followed_id: other_user_id)
  respond_to do |format|
    format.html { redirect_to user_path(other_user) }
    format.js
  end
end

//similarly
def destroy
  //find the other_user, if relationship exists, destroy it
end

然后在你的html

__ _follow.html.erb

<%= form_for(:relationship, url: relationships_path, remote: true) do |f| %>
  <div><%= f.hidden_field :followed_id, value: @user.id %></div>
  <%= f.submit "Follow", class: "btn btn-large btn-primary" %>
<% end %>

同样,部分 _unfollow.html.erb 的提交按钮的值更改为Unfollow.

(虽然我不是隐藏字段的忠实粉丝。你也可以设置嵌套路由。)

所以现在你可以在你的模型中有一个方法 say is_following(user),它会检查current_user和 `other_user 是否有关系。并在显示页面中说

<% if current_user.is_following(other_user) %>
  <%= render 'unfollow' %>
<% else %>
  <%= render 'follow' %>
<% end %>

然后你需要你的js.erb文件来为你处理 JavaScript 响应。在这种情况下,名称create.js.erbedit.js.erb 例如:

$("some_selector_name).html("<%= j render('shared/follow') %>")

关于状态机(我觉得这对于两种状态关系来说有点矫枉过正)可以在你的用户模型中使用可能 就像

state_machine :state, initial: :unfollow
  event :confirm_follow do
    transition to: :follow, from: :unfollow
  end
  state :follow do
    def is_following?(user) 
      // do some checks
      //!!relationships.find(user.id)
    end
  end
end
于 2014-11-06T06:35:52.330 回答