From 7d9eed3dfb5026f1cfa23b679244590cfc7986a4 Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Thu, 2 Jul 2015 16:54:05 +0200 Subject: [PATCH] Refactored channel backend call and replaced eval with Object.const_get. --- app/models/channel.rb | 17 +++++++++++++---- app/models/channel/email_send.rb | 25 ++++++++++++++++++------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/app/models/channel.rb b/app/models/channel.rb index 79716bbae..47990ab05 100644 --- a/app/models/channel.rb +++ b/app/models/channel.rb @@ -7,13 +7,22 @@ class Channel < ApplicationModel channels = Channel.where( 'active = ? AND area LIKE ?', true, '%::Inbound' ) channels.each { |channel| begin - c = eval 'Channel::' + channel[:adapter].upcase + '.new' # rubocop:disable Lint/Eval - c.fetch(channel) + # we need to require each channel backend individually otherwise we get a + # 'warning: toplevel constant Twitter referenced by Channel::Twitter' error e.g. + # so we have to convert the channel name to the filename via Rails String.underscore + # http://stem.ps/rails/2015/01/25/ruby-gotcha-toplevel-constant-referenced-by.html + require "channel/#{channel[:adapter].underscore}" + + channel_object = Object.const_get("Channel::#{channel[:adapter]}") + channel_instance = channel_object.new + + channel_instance.fetch(channel) + + channel_instance.disconnect rescue => e - logger.error "can't use " + 'Channel::' + channel[:adapter].upcase + logger.error "Can't use Channel::#{channel[:adapter]}" logger.error e.inspect logger.error e.backtrace - c.disconnect end } end diff --git a/app/models/channel/email_send.rb b/app/models/channel/email_send.rb index 97601772f..384c3f347 100644 --- a/app/models/channel/email_send.rb +++ b/app/models/channel/email_send.rb @@ -3,15 +3,26 @@ require 'net/imap' module Channel::EmailSend - def self.send(attr, notification = false) - channel = Channel.find_by( area: 'Email::Outbound', active: true ) + def self.send(article, notification = false) begin - c = eval 'Channel::' + channel[:adapter] + '.new' # rubocop:disable Lint/Eval - c.send(attr, channel, notification) + # we need to require the channel backend individually otherwise we get a + # 'warning: toplevel constant Twitter referenced by Channel::Twitter' error e.g. + # so we have to convert the channel name to the filename via Rails String.underscore + # http://stem.ps/rails/2015/01/25/ruby-gotcha-toplevel-constant-referenced-by.html + require "channel/#{channel[:adapter].underscore}" + + channel_object = Object.const_get("Channel::#{channel[:adapter]}") + channel_instance = channel_object.new + + channel_instance.send(article, channel, notification) + + channel_instance.disconnect rescue => e - Rails.logger.error "can't use " + 'Channel::' + channel[:adapter] - Rails.logger.error e.inspect - Rails.logger.error e.backtrace + logger.error "Can't use Channel::#{channel[:adapter]}" + logger.error e.inspect + logger.error e.backtrace end + + end end