【发布时间】:2016-09-23 16:45:57
【问题描述】:
我是一名初级开发人员,尝试编写代码来区分用户拥有的哔声和其他用户授权的哔声。
哔声来自用户拥有的设备。所有者可以授权其他用户使用该设备并接收他们自己的哔声警报。这给了我们两种不同类型的哔声:拥有的哔声和授权的哔声。我希望授权用户能够同时删除多个哔声事件并且只删除他们自己的哔声事件,而我希望所有者能够删除多个哔声和这些哔声对应的事件。
我正在处理的应用程序非常大,并且在架构上已设置此功能,以便所有者仅删除单个哔声。
哔声事件通过一个方法与一个单独的应用程序对话,该应用程序通过 device_broker 方法处理事件的删除。
我最终做的是一个带有 if 语句的事务,然后循环遍历每个迭代器,检查通过的每个哔声是否由用户拥有或授权。
我的问题是我的 broker_mock 测试没有收到任何参数。当我在代码上使用调试器时,这些方法似乎都在工作,所以我很困惑。在每个循环中使用 if 语句是个好主意吗?同样将其全部包装在事务中意味着如果一件小东西坏了,它就不起作用。有更好的选择吗?
感谢您提供的任何智慧或光明。
beeps_controller.rb
def bulk_deletion
BulkBeepRemover.run!(params[:beep_ids], current_user)
end
bulk_beep_remover.rb
class BulkBeepRemover
class Unauthorized < StandardError; end;
attr_reader :beep_ids, :user, :beeps
attr_accessor :owned_beeps, :unowned_beeps
def self.run!(beep_ids, user)
new(beep_ids, user).run!
end
def initialize(beep_ids, user)
@beep_ids = beep_ids
raise Unauthorized if user.nil?
@user = user
end
def beeps
@beeps ||= Beep.finished.find(beep_ids)
end
def device_broker
@device_broker ||= $device_broker
end
attr_writer :device_broker
def run!
#handles deletion of the owned beeps
Beep.transaction do
beeps.each do |beep|
if beep.device.is_owner?(user)
beep.destroy
remove_beep_event(beep.id)
end
# elsif beep.device.is_authorized?(user) logic goes here
end
end
end
private
def remove_beep_event(beep_id)
device_broker.publish('beep_deleted', { beep_id: beep_id })
end
dings_spec.rb
describe "POST /clients_api/beeps/bulk_deletion" do
let(:user_id) { user.id }
let!(:shared_beep_1) { create(:beep, id: 33, device: authorized_device, state: :completed) }
let!(:shared_beep_2) { create(:beep, id: 34, device: authorized_device, state: :completed) }
let!(:owned_beep_1) { create(:beep, id: 35, device: owned_device, state: :completed) }
let!(:owned_beep_2) { create(:beep, id: 36, device: owned_device, state: :completed) }
before do
post "/clients_api/beeps/:beep_id/bulk_deletion", default_params.merge(beep_ids: [shared_beep_1.id, shared_beep_2.id, owned_beep_1.id, owned_beep_2.id], user_id: user.id)
allow_any_instance_of(BulkBeepRemover).to receive(:device_broker).and_return(broker_mock)
end
context "the owner's array of beep ids" do
let(:beep_id) { owned_beep_2.id }
it "deletes the beeps" do
expect { Beep.find(beep_id) }.to raise_error(ActiveRecord::RecordNotFound)
end
it "publishes the owner beep_deleted event" do
expect(broker_mock).to have_received(:publish).with("beep_deleted", { beep_id: beep_id })
end
end
end
end
【问题讨论】:
标签: ruby-on-rails if-statement transactions conditional