停止Activerecord加载Blob列

时间:2008-09-18 18:05:01

标签: activerecord lazy-loading blob

除非明确要求,否则如何告诉Activerecord不加载blob列?我的旧数据库中有一些非常大的blob必须被排除在“普通”对象之外。

4 个答案:

答案 0 :(得分:12)

我刚刚使用导轨3遇到了这个问题。

幸运的是,解决起来并不困难。我设置了一个default_scope,它从结果中删除了我不想要的特定列。例如,在模型中,我有一个xml文本字段,可能很长,在大多数视图中都没有使用。

default_scope select((column_names - ['data']).map { |column_name| "`#{table_name}`.`#{column_name}`"})

您将从解决方案中看到我必须将列映射到完全限定版本,以便我可以通过关系继续使用模型,而不会在属性中出现歧义。稍后你想让这个领域只是在另一个.select(:data)上加以包含它。

答案 1 :(得分:4)

我相信您可以要求AR在您的调用中加载特定列以查找:

MyModel.find(id, :select => 'every, attribute, except, the, blobs')

但是,在添加列时需要更新,因此不太理想。我认为没有任何方法可以在rails中专门排除一个列(也不是在单个SQL选择中)。

我想你可以这样写:

MyModel.find(id, :select => (MyModel.column_names - ['column_to_exclude']).join(', '))

在你接受我的话之前测试这些。 :)

答案 2 :(得分:4)

fd的答案大多是正确的,但ActiveRecord doesn't currently accept an array作为:select参数,因此您需要将所需的列连接到逗号分隔的字符串中,如下所示:

desired_columns = (MyModel.column_names - ['column_to_exclude']).join(', ')
MyModel.find(id, :select => desired_columns)

答案 3 :(得分:1)

一种干净的方法,无需更改您在应用中的其他位置编码的方式,即不会弄乱:select个选项

  

无论出于何种原因,您需要或选择将blob存储在数据库中。   但是,您不希望在同一个表中混合使用blob列   常规属性。 BinaryColumnTable可帮助您存储所有blob   一个单独的表,由ActiveRecord模型透明地管理。   (可选)它可以帮助您记录blob的内容类型。

     

http://github.com/choonkeat/binary_column_table

用法很简单

Member.create(:name => "Michael", :photo => IO.read("avatar.png"))
#=> creates a record in "members" table, saving "Michael" into the "name" column
#=> creates a record in "binary_columns" table, saving "avatar.png" binary into "content" column

m = Member.last #=> only columns in "members" table is fetched (no blobs)
m.name          #=> "Michael"
m.photo         #=> binary content of the "avatar.png" file