Skip to content

Instantly share code, notes, and snippets.

@acoffman
Created May 23, 2012 17:45
Show Gist options
  • Save acoffman/2776617 to your computer and use it in GitHub Desktop.
Save acoffman/2776617 to your computer and use it in GitHub Desktop.
hangoff active record plugin
def with_hangoff_table(relation_name, opts={})
hangoff_table = reflections[relation_name].table_name
foreign_key = reflections[relation_name].foreign_key
name_column = opts[:name_column] || :attribute_name
value_column = opts[:value_column] || :attribute_value
(class << self; self; end).send(:define_method, relation_name) do |params|
table_alias = hangoff_table + SecureRandom.hex(4)
join_string = "INNER JOIN #{hangoff_table} AS #{table_alias} ON #{table_alias}.#{foreign_key} = #{table_name}.#{primary_key}"
scoped.joins(join_string).where(params.inject({}) do |hash, vals|
hash["#{table_alias}.#{name_column}"] = vals[0]
hash["#{table_alias}.#{value_column}"] = vals[1]
hash
end)
end
end
has_many :drug_categories, foreign_key: :drug_name_report_id
with_hangoff_table :drug_categories, name_column: :category_name, value_column: :category_value
#Now you have a class method named after the relation where you can pass a "where" style hash of params to query the hangoff table as if it had columns
MyModel.drug_categories(drug_type: 'biomedical')
#drug type is actually a value in drug_categories underlying table in the :category_name column and 'biomedical' is in the same row in the :category_value column
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment