Rails 4 public_activity 有两种所有者

Rails 4 public_activity with two types of owner

我在我的应用程序中使用 public_activity gem 并跟踪创建记录的所有者以跟踪事件模型,我正在使用设计并且我有两种类型的用户,个人和公司,我的代码是跟踪所有者

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

end

这里的问题是,如果公司已登录,我想将所有者跟踪为 current_company,但 public_activity gem 不提供多种所有者类型

我想跟踪,如果 current_individual 已登录,则所有者类型和 ID 将是个人,如果公司已登录,则根据那个。

我正在做的是

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

但我在个人登录时获取所有者 ID 和类型,但在公司登录时未获取所有者类型和 ID

其实owner是多态的可以看出here:

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

我有一个庞大的模型元素网络,可用于为任何事物创建 "preplan" 从单个建筑物到整个大学校园,其中包含数十个结构、数百个消防栓...以及一个结构可以有各种各样的东西(屋顶、通道(门)、危险材料、火灾探测系统、保护系统、洒水装置等)。

任何元素可以有一张或多张张照片attached/edited/deleted.

多态所有者: 我喜欢装饰 activity 跟踪以显示谁 added/edited/deleted 一张照片以及“拥有" 元素,不管 class.

因此,可重复使用的部分用于为任何元素设置一个漂亮的 "Add Photos" 拖放着陆区。 partial 被传递给本地来告诉“owning”元素是什么(结构、屋顶或警报系统):

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

在那个局部中,拥有元素被进一步解析了......(可能是不必要的,可以只传递所有者并在控制器中解析它,现在我看到了!)

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

然后控制器有一些动作来处理"owning"对象...

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

控制器使用高度多态的“owner”class(包括 HasActivities 模块,包含 public_activity gem):

  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