Rails 4 public_activity с двумя типами владельцев
Я использую gem 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
но я получаю идентификатор владельца и тип, когда человек вошел в систему, но не получаю тип владельца и идентификатор, когда компания вошла
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 }
Я надеюсь, что мой подход не заставляет людей кровоточить. Возможно, это не лучший код для копирования (рад за советы), но я надеюсь, что идея полезна (и она работает):-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 с этим очень полиморфным классом "владельца" (который включает модуль 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