Rails 4 public_activity с двумя типами владельцев

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

class Event < ActiveRecord::Base
  include PublicActivity::Model
  tracked owner: ->(controller, model) { controller && controller.current_individual }

end

Здесь проблема в том, что я хочу отслеживать владельца как current_company, если компания вошла в систему, но гем public_activity не предоставляет несколько типов владельцев

Я хочу отследить, что если current_individual вошел в систему, то тип и идентификатор владельца будут индивидуальными, и если компания войдет в систему, то в соответствии с этим.

что я делаю

class Event < ActiveRecord::Base
  include PublicActivity::Model
  tracked owner: ->(controller, model) { controller &&  controller.individual_signed_in? ? controller.current_individual : controller.current_company  }
end

но я получаю идентификатор и тип владельца, когда человек входит в систему, но не получаю тип и идентификатор владельца, когда компания входит в систему


person user4965201    schedule 15.09.2015    source источник


Ответы (2)


На самом деле owner полиморфен, как видно здесь:

create_table :activities do |t|
  t.belongs_to :trackable, :polymorphic => true
  t.belongs_to :owner, :polymorphic => true
  t.string  :key
  t.text    :parameters
  t.belongs_to :recipient, :polymorphic => true

  t.timestamps
end

Так что не проблема назначить владельца другого типа.

Если вы хотите назначить компанию владельцем при входе в систему пользователя компании и человека при входе в личную учетную запись, вам нужно просто внести соответствующие изменения в свой код:

tracked owner: ->(controller, model) { controller.current_user.organization? ? controller.current_user.organization : controller.current_user.person }
person dimakura    schedule 15.09.2015
comment
я сделал, как этот отслеживаемый владелец: -›(контроллер, модель) {контроллер && controller.individual_signed_in? ? controller.current_individual : controller.current_company } я получаю идентификатор и тип владельца, когда человек входит в систему, но не получаю тип и идентификатор владельца, когда компания входит в систему - person user4965201; 15.09.2015
comment
позвольте мне поставить это в вопросе - person user4965201; 15.09.2015
comment
вы имеете в виду, когда вы сохраняете активность как компанию, она не записывается в базу данных? - person dimakura; 15.09.2015
comment
нет, я не получаю тип владельца и идентификатор для компании, но получаю для человека - person user4965201; 15.09.2015
comment
какой у вас current_user метод. тоже User модель? - person dimakura; 15.09.2015
comment
я использую devise, а devise дает вспомогательный метод current_user - person user4965201; 15.09.2015
comment
Давайте продолжим обсуждение в чате. - person dimakura; 15.09.2015
comment
individual_signed_in? метод - person dimakura; 15.09.2015
comment
да, это способ узнать, вошел ли человек в систему и company_signed_in? узнать, зарегистрирована ли компания - person user4965201; 16.09.2015
comment
@ user4965201 Я имею в виду, как это выглядит? - person dimakura; 16.09.2015
comment
я не могу понять, что такое Individual_signed_in? выглядит как. а это похоже на user_signed_in? по разработке и то же самое касается company_signed_in? - person user4965201; 16.09.2015

Я надеюсь, что мой подход не заставляет людей кровоточить глаза. Возможно, это не лучший код для копирования (рад за подсказки), но я надеюсь, что идея будет полезной (и она действительно работает) :-p

У меня есть большая сеть элементов модели, которые можно использовать для создания «предварительного плана» чего угодно, от одного здания до целого университетского городка, состоящего из десятков строений, сотен пожарных гидрантов... И в строении могут быть все виды вещи (кровля, входы (двери), опасные материалы, системы обнаружения пожара, системы защиты, спринклеры и т. д.).

К любому элементу может быть прикреплена/отредактирована/удалена одна или несколько фотографий.

Полиморфный владелец: мне нравится украшать отслеживание активности, чтобы показать, кто добавил/редактировал/удалил фото и для какого элемента владеет, независимо от класса.

Таким образом, повторно используемый частичный элемент используется для создания красивой целевой зоны перетаскивания «Добавить фотографии» для любого элемента. Партиал передается локальному элементу, чтобы сообщить, что является элементом владения (структурой, крышей или системой сигнализации):

= render partial: 'photos/photos', locals: {owner: item}

И внутри этого партиала элемент-владелец анализируется немного дальше... (вероятно, ненужный, можно было бы просто передать владельца и проанализировать его в контроллере, теперь, когда я смотрю на это!)

= link_to new_photo_path(:owner_id => owner, :owner_class => owner.class, :tag => owner.class::TAG),

Затем у контроллера есть некоторые действия для работы с «владеющим» объектом...

class PhotosController < ApplicationController

  before_action :set_owning_object, only: [:new, :index]
  before_action :get_owning_object, only: [:create, :update]
  ...      
  def set_owning_object
    @owner_class = params["owner_class"]
    @owner_id = params["owner_id"]
    @photo_tag = params["tag"]
    session[:owner_class] = @owner_class if @owner_class
    session[:owner_id] = @owner_id if @owner_id
    session[:photo_tag] = @photo_tag if @photo_tag
    # Unsafe reflection method constantize called with parameter value
    # Let's whitelist the allowable classes that can have Photos
    if @owner_class
      if (%w(Preplan Structure Organization PreplanLayout StagingArea) + Structure::Default_Elements).include? @owner_class
        @owning_object = (@owner_class.constantize).find(@owner_id)
      else
        Rails.logger.warn("OWNING CLASS NEEDS TO BE ADDED: #{@owner_class} was not cleared for use in #{__method__}.")
      end
    else
      @owning_object = nil
    end

  end

И контроллер вручную добавляет действия под нужными действиями CRUD с помощью этого высокополиморфного класса «owner» (который включает модуль HasActivities, включающий гем public_activity):

  def create
    authorize Photo
    @photo = Photo.new(photo_params)
    @photo.tags << @photo_tag
    add_photo(@owning_object, @photo)

    respond_to do |format|
      if @photo.save
        if @owning_object.respond_to? :create_activity
          @owning_object.create_activity(:add_photo,
                                         owner: view_context.current_user,
                                         organization: view_context.current_org,
                                         recipient: @owning_object,
                                         parameters: { name: @photo.caption, file: @photo.photo_name, owner: @owning_object.name })
        end
        pseudo_url = owning_object_url(@owning_object)
        format.html {
          redirect_to pseudo_url, notice: "Photo was successfully added."
        }
        format.json {render json: { photo: render_to_string(partial: 'photos/photo', layout: false, :formats => [:html], locals: { photo: @photo, photo_counter: @photo.id }) }}
      else
        format.html {render action: 'new'}
        format.json {render json: { error: @photo.errors.full_messages.join(',') }, :status => 406}
      end
    end
  end

  def update
    authorize @photo
    if @photo.update_attributes(photo_params)
      @photo.create_activity(:update,
                             owner: view_context.current_user,
                             organization: view_context.current_org,
                             recipient: @owning_object,
                             parameters: { name: @photo.caption, file: @photo.photo_name })
      respond_to do |format|
        format.js
      end
    end
  end

  def destroy
    authorize @photo
    @photo.create_activity(key: 'photo.destroy',
                           owner: current_user,
                           organization: view_context.current_org,
                           parameters: { name: @photo.caption, file: @photo.photo_name })
    @photo.destroy

    respond_to do |format|
      format.html {redirect_to :back}
      format.json {head :no_content}
    end
  end

Вышеупомянутый модуль HasActivities:

module HasActivities
  extend ActiveSupport::Concern

  included do
    include PublicActivity::Common
  end
end

Пример полиморфных действий

person Jon Kern    schedule 31.08.2017