- findしたものをARにどうやって詰めるのか
lib/active_record/base.rb:430 find_by_sql
# Works like find(:all), but requires a complete SQL string. Examples:
# Post.find_by_sql "SELECT p.*, c.author FROM posts p, comments c WHERE p.id = c.post_id"
# Post.find_by_sql ["SELECT * FROM posts WHERE author = ? AND created > ?", author_id, start_date]
def find_by_sql(sql)
connection.select_all(sanitize_sql(sql), "#{name} Load").collect! { |record| instantiate(record) }
end
lib/active_record/connection_adapters/abstract/database_statements.rb:6
def select_all(sql, name = nil)
end
lib/active_record/connection_adapters/mysql_adapter.rb:170
def select_all(sql, name = nil) #:nodoc:
select(sql, name)
end
lib/active_record/connection_adapters/mysql_adapter.rb:320
def select(sql, name = nil)
@connection.query_with_result = true
result = execute(sql, name)
rows = []
if @null_values_in_each_hash
result.each_hash { |row| rows << row }
else
all_fields = result.fetch_fields.inject({}) { |fields, f| fields[f.name] = nil; fields }
result.each_hash { |row| rows << all_fields.dup.update(row) }
end
result.free
rows
end
lib/active_record/base.rb:887
# Finder methods must instantiate through this method to work with the single-table inheritance model
# that makes it possible to create objects of different types from the same table.
def instantiate(record)
object =
if subclass_name = record[inheritance_column]
if subclass_name.empty?
allocate
else
require_association_class(subclass_name)
begin
compute_type(subclass_name).allocate
rescue NameError
raise SubclassNotFound,
"The single-table inheritance mechanism failed to locate the subclass: '#{record[inheritance_column]}'. " +
"This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " +
"Please rename this column if you didn't intend it to be used for storing the inheritance class " +
"or overwrite #{self.to_s}.inheritance_column to use another column for that information."
end
end
else
allocate
end
object.instance_variable_set("@attributes", record)
object
end
なぜ allocate
?? newしたらだめなの?
def initialize(attributes = nil)
@attributes = attributes_from_column_definition
@new_record = true
ensure_proper_type
self.attributes = attributes unless attributes.nil?
yield self if block_given?
end
DB定義からattributesを組み立てる
# Initializes the attributes array with keys matching the columns from the linked table and
# the values matching the corresponding default value of that column, so
# that a new instance, or one populated from a passed-in Hash, still has all the attributes
# that instances loaded from the database would.
def attributes_from_column_definition
self.class.columns.inject({}) do |attributes, column|
attributes[column.name] = column.default unless column.name == self.class.primary_key
attributes
end
end
つぎにこれ。
@new_record = true
たしかに検索結果は new_record
ではないしな
# Allows you to set all the attributes at once by passing in a hash with keys
# matching the attribute names (which again matches the column names). Sensitive attributes can be protected
# from this form of mass-assignment by using the +attr_protected+ macro. Or you can alternatively
# specify which attributes *can* be accessed in with the +attr_accessible+ macro. Then all the
# attributes not included in that won't be allowed to be mass-assigned.
def attributes=(attributes)
return if attributes.nil?
attributes.stringify_keys!
multi_parameter_attributes = []
remove_attributes_protected_from_mass_assignment(attributes).each do |k, v|
k.include?("(") ? multi_parameter_attributes << [ k, v ] : send(k + "=", v)
end
assign_multiparameter_attributes(multi_parameter_attributes)
end