Я хочу отобразить таблицы поиска в базе данных в хэш, хорошая идея? - PullRequest
4 голосов
/ 30 июля 2011

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

table name: donations

id
amount
note
user_id
appeal_id
donation_status_id
donation_type_id
is_anonymous
created_at
updated_at

Поля * donation_status_id * и * donation_type_id * относятся к справочным таблицам.Так что в моем коде есть несколько случайных мест, где я делаю вызовы, подобные этому:

my_donation = Donation.find(params[:id])
if my_donation.donation_status_id == DonationStatus.find_by_name("completed").id
#do something
end

На мой неопытный взгляд, одноразовый запрос к таблице DonationStatus кажется невероятно расточительным, но я не вижулюбой другой хороший способ сделать это.Первая идея, о которой я подумал, состояла в том, чтобы при запуске приложения считывать все мои таблицы поиска в хэш, а затем просто запрашивать их, когда мне это нужно.Но есть ли лучший способ сделать то, что я пытаюсь сделать?Не стоит ли мне беспокоиться о таких запросах?Спасибо!

Ответы [ 3 ]

2 голосов
/ 30 июля 2011

Как насчет положить его в константу?Например, что-то вроде этого:

class DonationStatus < ActiveRecord::Base
  COMPLETED_DONATION_ID = DonationStatus.find_by_name("completed").id
  PENDING_DONATION_ID   = DonationStatus.find_by_name("pending").id
  # ...
end

class DonationsController < ApplicationController
  def some_action
    my_donation = Donation.find(params[:id])
    if my_donation.donation_status_id == DonationStatus::COMPLETED_DONATION_ID
    #do something
  end
end

Таким образом, DonationStatus.find_by_name("pending").id исполняется ровно один.Конечно, я предполагаю, что эта таблица будет меняться не часто.

Кстати, я научился этому трюку в книге Дэна Чака Enterprise Rails .

РЕДАКТИРОВАТЬ: Я забыл упомянуть: на практике я объявляю константы следующим образом:

COMPLETED_DONATION_ID = DonationStatus.find_by_name("completed").id rescue "Can't find 'completed' in donation_statuses table"
2 голосов
/ 30 июля 2011

Поскольку у вас есть две модели, вы должны использовать ассоциации моделей ActiveRecord при построении моделей.

class Donation
  has_one :donation_status
end

class DonationStatus
 belongs_to :donation
end

Затем, когда вы сделаете

my_donation = Donation.find(params[:id])
if my_donation.donation_status.status_name == 'complete'
  #do something
end

Для получения дополнительной информации, возможно, вы захотите прочитать, как rails выполняет ассоциации моделей http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html Не беспокойтесь опроизводительность, рельсы позаботились об этом для вас, если вы будете следовать, как это должно быть сделано

1 голос
/ 30 июля 2011

Что вы можете сделать, это добавить этот метод к Donation:

# Donation.rb
def completed?
    self.donation_status.name == 'completed' ? true : false
end

А затем просто выполните my_donation.completed?.Если это вызывается во второй раз, Rails будет искать в кеше, а не в БД.

Вы можете добавить memcached, если хотите, или использовать кеширование Rails дальше, и выполнить:

def completed?
    return Rails.cache.fetch("status_#{self.donation_status_id}_complete") do
        self.donation_status.name == 'completed' ? true : false
    end
end

То, что это будет делать, это создать хеш-ключ, называемый (например) «status_1_complete», и, если он не был определен в первый раз, оценит блок и установит значение.В противном случае он просто вернет значение.Таким образом, если у вас было 1 000 000 000 пожертвований, и у каждого из них было donation_status 1, оно попадало бы прямо в кэш.memcached довольно быстрый и популярный.

...