Проблемы с реализацией ajax. если оператор не будет работать

Я не уверен, в чем проблема, чтобы узнать, о чем именно я прошу, но я сделаю все возможное. Я попытался выделить жирным шрифтом то, что, по моему мнению, является проблемой, чтобы прояснить ситуацию.

Я работаю с ajax в первый раз. В приложении пользователь (1) ищет пользователя (2), найдя пользователя (2), пользователь (1) может нажать кнопку «добавить отношения», которая отправляет запрос на отношения пользователю (2). кнопка «добавить отношения» должна сразу же измениться на «запрошенные отношения», а затем, после обновления страницы, кнопка должна измениться на «изменить отношения».

«добавить отношения» = отношения еще не существуют «запрошенные отношения» = ожидающие отношения существуют, действует как мгновенное сообщение об успешном выполнении «изменить отношения» = ожидающие отношения существуют или существуют принятые отношения

Все работает, за исключением последней части, где кнопка должна измениться на «изменить отношения» после обновления страницы браузера. Вместо этого появляется «добавить отношение»

Есть идеи, что эта кнопка «редактировать отношения» не появится? Я использую конечный автомат, драпировщик и драгоценные камни js-routes.

просмотр/пользователи/индекс:

где при поиске пользователя (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 [email protected] (14.2ms)
Date: Thu, 06 Nov 2014 16:35:26 +1100
From: [email protected]
To: [email protected]
Message-ID: <[email protected]>
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) ищу пример пользователя-24 (идентификатор пользователя = 25), а затем нажимаю кнопку «добавить отношение» (как показано в sqlitebrowser: (см. внизу изображения две строки, относящиеся к этому пример)

таблица отношений БД

ИЗМЕНИТЬ:

пользователи/контроллер:

  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

person sss333    schedule 05.11.2014    source источник
comment
вы пробовали это из консоли рельсов? Мы не видим ваш код конечного автомата или какой-то код, в котором вы меняете состояние или какое-то значение в базе данных. И тип данных - json, который, я думаю, может быть «сценарием».   -  person argentum47    schedule 06.11.2014
comment
Спасибо за ответ @argentum47! как мне попробовать это из консоли рельсов? Я не уверен, что вы подразумеваете под «типом данных является json, который, я думаю, может быть« скриптом ».'? Я новичок в этом. Однако я добавил код для конечного автомата (модель и миграция базы данных)   -  person sss333    schedule 06.11.2014
comment
Я также только что добавил вывод терминала, показывающий, что происходит, когда нажимается кнопка «добавить отношение». похоже, что он обрабатывается как JSON. Если я использую sqlitebrowser, я вижу, что 2 отношения были созданы при нажатии кнопки «добавить отношение». Я сейчас тоже добавлю фото к вопросу, чтобы вы могли его увидеть.   -  person sss333    schedule 06.11.2014
comment
Вы отправляете запрос ajax, поэтому ваш тип данных должен быть «скриптом», а не «json» в вашем javascript.   -  person argentum47    schedule 06.11.2014
comment
@ argentum47 я изменил его, «кнопка запроса отношений больше не будет отображаться, терминал говорит, что он обрабатывается как html, и я получаю «SQLite3:: BusyException: база данных заблокирована: ...», я изменил его обратно на json, и я я все еще получаю «SQLite3:: BusyException: база данных заблокирована: ...». теперь я еще больше потерял   -  person sss333    schedule 06.11.2014
comment
Я отправил ответ, посмотрите, сработает ли он для вас, иначе настройте чат или зайдите на канал irc #rubyonrails, есть люди лучше меня: P   -  person argentum47    schedule 06.11.2014
comment
@argentum47 как попасть на irc-канал #rubyonrails? Я никогда не слышал об этом раньше? также! Я перезапустил свой комп, и ошибка sqlite исчезла. Я снова попробовал идею сценария, он обрабатывает, поскольку JS в выводе терминала делает все, что он использует, и запускает запрос на получение, чтобы показать пользователю, которого я пытаюсь подружить. представление в браузере не меняется, но по-прежнему показывает «добавить отношение».   -  person sss333    schedule 06.11.2014
comment
также я не уверен, почему, но кнопка «запрошенные отношения» больше не будет появляться, когда я нажимаю «добавить отношения» (как это было, когда я впервые разместил вопрос) - если я использую json или script..   -  person sss333    schedule 06.11.2014
comment
У вас есть в вашем контроллере answer_to foramt.js?   -  person argentum47    schedule 06.11.2014
comment
Нет. но что было бы, если бы я использовал скрипт правильно? если я вернусь к «json», не должно ли снова работать исходное поведение? Консоль javascript в браузере показывает: POST localhost:3000/relationships?relationship%5Bfollowed_id%5D =44 412 (не удалось предварительное условие)   -  person sss333    schedule 06.11.2014
comment
если у вас есть json, то вам нужно написать format.json {...} У вас есть в вашем контроллере answer_to foramt.js? проверьте, если current_user.following.include?(user.id) если эта строка выполняется правильно, я предполагаю, что это условие ложно, поэтому кнопки не меняются. Остальные вроде нормально выглядят. meblog.herokuapp.com/public/rCDk80M3glDaTo4DzEwSLA шаги для присоединения к irc   -  person argentum47    schedule 06.11.2014
comment
Давайте продолжим обсуждение в чате.   -  person argentum47    schedule 06.11.2014
comment
Затем я добавил действие создания для пользовательского контроллера. здесь находится часть формата ответа. Я получил часть «запрошенные отношения», чтобы показать снова, обработав часть предварительного условия этого действия в части else format.json. единственная часть, которая не работает, - это кнопка «редактировать отношения», которая не отображается при обновлении страницы. вместо этого показывает «добавить отношения»   -  person sss333    schedule 06.11.2014


Ответы (1)


Хотя я не могу исправить эту вашу ошибку, вы можете сделать это так.

  1. Имейте form_for или link_to с опцией remote true.
  2. controller и route, чтобы ответить на ваш action

Например:

В вашем routes.rb

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

И в вашем relationships_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.

(Хотя я не большой поклонник скрытых полей. Вы также можете настроить вложенные маршруты.)

Итак, теперь у вас может быть метод в вашей модели, скажем, 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.erb и edit.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
person argentum47    schedule 06.11.2014
comment
БОЛЬШОЕ СПАСИБО! Вы были просто великолепны, проведя со мной так много времени, помогая мне изучать JS и ROR. Сегодняшний вечер был неоценим для моего обучения! - person sss333; 06.11.2014