除非明确要求,否则我如何告诉 Activerecord 不加载 blob 列?我的遗留数据库中有一些相当大的 blob 必须排除在“普通”对象之外。
4 回答
我刚刚使用rail 3遇到了这个问题。
幸运的是,解决起来并不难。我设置了一个default_scope
从结果中删除了我不想要的特定列。例如,在我的模型中,有一个可能很长的 xml 文本字段在大多数视图中都没有使用。
default_scope select((column_names - ['data']).map { |column_name| "`#{table_name}`.`#{column_name}`"})
您将从解决方案中看到,我必须将列映射到完全限定的版本,这样我才能通过关系继续使用模型,而不会在属性中产生歧义。稍后,如果您确实想要该字段,只需添加另一个字段即可.select(:data)
将其包含在内。
我相信您可以要求 AR 在您的调用中加载特定列以查找:
MyModel.find(id, :select => 'every, attribute, except, the, blobs')
但是,这需要在添加列时进行更新,因此并不理想。我认为没有任何方法可以专门排除 rails 中的一列(也没有在单个 SQL 选择中)。
我想你可以这样写:
MyModel.find(id, :select => (MyModel.column_names - ['column_to_exclude']).join(', '))
不过,在你相信我的话之前先测试一下。:)
fd 的回答基本正确,但 ActiveRecord目前不接受数组作为 :select 参数,因此您需要将所需的列加入逗号分隔的字符串中,如下所示:
desired_columns = (MyModel.column_names - ['column_to_exclude']).join(', ')
MyModel.find(id, :select => desired_columns)
一种干净的方法,无需更改您在应用程序中其他位置的编码方式,即不会弄乱:select
选项
无论出于何种原因,您需要或选择将 blob 存储在数据库中。但是,您不希望将 blob 列与常规属性混合在同一个表中。BinaryColumnTable 帮助您将所有 blob 存储在单独的表中,由 ActiveRecord 模型透明地管理。或者,它可以帮助您记录 blob 的内容类型。
用法很简单
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