2013-07-10 3 views
0

У меня есть сайт Rails, который регистрирует простые действия, например, когда люди переходят в нижнюю и нижнюю стороны. Для каждого нового действия создается EventLog.Как запросить много полей, разрешающих NULL

Что делать, если пользователь меняет свое мнение? У меня есть обратный вызов after_create, который ищет дополнительные действия и удаляет оба, если находит последнюю пару. Для ясности я имею в виду, что если человек что-то упрекает и скоро отменяет, оба event_logs удаляются. Ниже следует мой обратный вызов.

# Find duplicate events by searching nearly all the fields in the EventLog table 
@duplicates = EventLog.where("user_id = ? AND event = ? AND project_id = ? AND ...,).order("created_at DESC") 

if @duplicates.size > 1 
    @duplicates.limit(2).destroy_all 
end 

Приведенный выше код не совсем работает, потому что если какой-либо из полей, оказывается нулевым, то запрос возвращает [].

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

+0

Ну, это просто sql, поэтому вы можете добавить 'user_id IS NULL ИЛИ user_id =? 'для каждого аргумента. Это будет уместно для вашего дела? – Matt

ответ

0

Если я понял это правильно,

некоторые поля могут быть нулевыми, и вы хотите, чтобы найти журналы активности, которые имеют такой же user_id, то же project_id проект или идентификатор может быть нулевым.

Так что, я думаю, этот запрос должен сработать для вас.

ActivityLog.where(user_id: <some_id> AND activity: <complementary_id> AND :project_id.in => [<some_project_id>, nil] ....) 

Таким образом, вы получите дополнительные журналы событий, где user_id такие же и идентификатор проекта может или не может присутствовать

class ActivityLog 
    QUERY_HASH = Proc.new{ {user_id: self.user_id, 
         activity: complementary_id(self.id), 
         and so on.... 
    } } 
+0

В моем случае любая комбинация полей может быть пуста, поскольку запись сохраняется - я могу использовать ваш метод для каждого поля, но он становится довольно длинным. – sscirrus

+0

Тогда возникает проблема с созданием хеша запроса. Вы можете хранить запрос в константе как proc, а затем экземпляр eval его во время выполнения. – nightf0x

0

Как насчет:

# event_log.rb 

def duplicate_attr_map 
    { 
    :user_id, 
    :project_id 
    } 
end 

def duplicates 
    attribs = duplicate_attr_map.reject_if(&:blank?) 

    query = attribs.map { |attr| "#{attr} = ?" }.join(' AND ') 
    values = attribs.map { |attr| self.send(attr) } 

    EventLog.where(query, *values).order("created_at DESC") 
end 

def delete_duplicates(n) 
    duplicates.limit(n).delete_all if duplicates.size > 1 
end 

# usage: 
# EventLog.find(1).delete_duplicates(2) 

не проверял, может быть улучшено

Смежные вопросы