阻止Activerecord加载Blob列

时间:2020-03-06 14:22:40  来源:igfitidea点击:

我如何告诉Activerecord除非明确要求,否则不要加载blob列?我的旧版数据库中有一些相当大的Blob,对于"普通"对象,必须将其排除在外。

解决方案

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

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

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

我猜你可以这样写:

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选项

For whatever reason you need or choose to store blobs in databases.
  Yet, you do not wish to mix blob columns in the same table as your
  regular attributes. BinaryColumnTable helps you store ALL blobs in
  a separate table, managed transparently by an ActiveRecord model. 
  Optionally, it helps you record the content-type of the 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

我只是用轨道3碰到了这个。

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

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

我们将从解决方案中看到,我必须将列映射到完全限定的版本,以便我可以继续通过关系使用模型,而属性没有歧义。稍后,我们确实希望在该字段上添加另一个.select(:data)以包含该字段。