4

我正在开发一个 Rails Web 应用程序,并且对如何在我的模型中使用查找表值感到困惑。这是我的应用程序中的示例模型:

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 表在这里似乎非常浪费,但我没有看到任何其他好的方法来做到这一点。我想到的第一个想法是在应用程序启动时将我所有的查找表读入一个散列,然后在我需要的时候查询它。但是有没有更好的方法来做我想做的事情?我不应该担心这样的查询吗?谢谢!

4

3 回答 3

2

把它放在一个常数中怎么样?例如,像这样:

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就被执行了一个。当然,我假设这张表不会经常更改。

顺便说一句,我在 Dan Chak 的书Enterprise Rails中学到了这个技巧。

编辑:我忘了提:在实践中,我声明这样的常量:

COMPLETED_DONATION_ID = DonationStatus.find_by_name("completed").id rescue "Can't find 'completed' in donation_statuses table"
于 2011-07-30T01:50:14.760 回答
2

由于您有两个模型,因此在构建模型时应该使用 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不要担心性能,rails 已经为你如果你按照应该怎么做

于 2011-07-30T01:54:51.983 回答
1

您可以做的是将此方法添加到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 非常快速和流行。

于 2011-07-30T01:44:12.633 回答