如何在Rails中将非数据库静态主数据(YAML文件)视为模型?
如何将YAML主数据当作Rails模型使用
完全可以实现,不用依赖Active Record,自己写个简单的类封装YAML数据,就能模拟出类似模型的常用功能,步骤如下:
1. 创建封装类
在app/models/item.rb里定义一个类,负责加载YAML数据并提供查询方法:
class Item # 加载并缓存YAML数据 def self.data @data ||= YAML.load_file(Rails.root.join('config', 'master_data', 'something.yml'))['items'] end # 获取所有条目 def self.all data.map { |item_info| new(item_info) } end # 按ID查找对应条目 def self.find(id) target = data.find { |item| item['id'] == id.to_i } target ? new(target) : nil end # 获取所有条目的名称列表 def self.names data.pluck('name') end # 实例化条目,方便调用属性 def initialize(attributes) @attributes = attributes end # 动态支持属性调用(比如item.name、item.description) def method_missing(name, *args) @attributes[name.to_s] || super end def respond_to_missing?(name, include_private = false) @attributes.key?(name.to_s) || super end end
2. 实际使用示例
- 在控制器中调用:
# 获取所有条目 @items = Item.all # 根据ID查询单个条目 @item = Item.find(params[:id]) # 获取所有条目名称列表 @item_names = Item.names
- 在视图里直接访问属性:
<% @items.each do |item| %> <div> <h3><%= item.name %></h3> <p><%= item.description %></p> </div> <% end %>
3. 优化小技巧
- 上面的代码已经用
@data ||=做了缓存,避免每次调用都重新读取YAML文件 - 如果需要支持YAML文件更新后热加载(不用重启服务),可以修改
data方法:
def self.data file_path = Rails.root.join('config', 'master_data', 'something.yml') current_mtime = File.mtime(file_path) # 检查文件是否更新,更新则重新加载 if @data.nil? || current_mtime > @last_loaded_at @data = YAML.load_file(file_path)['items'] @last_loaded_at = current_mtime end @data end
这样就能在控制器、视图等任何地方像使用Active Record模型一样操作YAML里的主数据了。
内容的提问来源于stack exchange,提问作者speed_star777
相关产品推荐
相关产品推荐

