Ruby on Rails: prevent from selecting a column by default
Assuming Rails 3 and a schema that looks like this:
create_table "entries", :force => true do |t|
t.string "title"
t.text "content"
t.datetime "created_at"
t.datetime "updated_at"
end
You can use the select
method to limit the fields that are returned like this:
class Entry < ActiveRecord::Base
default_scope select([:id, :title])
end
In the rails console, you should see something like this:
puts Entry.where(:id => 1).to_sql # => SELECT id, title FROM "entries" WHERE "entries"."id" = 1
When you do want to select all of the fields, you can use the unscoped
method like this:
puts Entry.unscoped.where(:id => 1).to_sql # => SELECT * FROM "entries" WHERE "entries"."id" = 1
As scoping, and default_scope mainly, gives many problems in use, my best way is to move big contents (binary, very large texts) to separate table.
create_table "entries", :force => true do |t|
t.string "title"
# ... more small sized attributes of entries
t.timestamps
end
create_table "entry_contents", :force => true do |t|
t.references :entries, foreign_key: true
t.text "content"
t.timestamps
end
class Entry ...
# reference
has_one :entry_content
# build entry_content for every new entry record
after_initialize do |entry|
entry.build_entry_content unless entry.entry_content.present?
end
end
This limits loading big data only when needed.
Entry.find(1).entry_content.content