I have a table that has set entries. I would like to access those entries as variables in both my models and controllers without querying the database every time to set those variables.
I am able to get it to work by creating duplicate "concerns" for my models and controllers. I could also set global variables in my ApplicationController. Or i could initialize them in every place that I need them. What would be the correct rails way to set and access global variables that can be accessed in both controllers and models?
class ItemType
has_many :items
end
class Item
belongs_to :item_type
belongs_to :foo
end
class Foo
has_many :items
def build_item
bar_item_type = ItemType.find_by(:name => "bar")
self.items.build(
:foo_id => self.id,
:item_type_id => bar_item_type.id
)
end
end
class ItemsController
def update
bar_item_type = ItemType.find_by(:name => "bar")
@item.update(:item_type_id => bar_item_type.id)
end
end
In the example, you can see that I am declaring the bar_item_type variable in both my Foo model and my ItemsController. I would like to DRY up my code base by being able to create and access that variable once for my rails project instead of having to make that same database call everywhere.
I would advocate against such hard-coded or DB state-dependent code. If you must do it, here's how one of the ways I know it can be done:
# models
class ItemType < ActiveRecord::Base
has_many :items
# caches the value after first call
def self.with_bar
@@with_bar ||= transaction { find_or_create_by(name: "bar") }
end
def self.with_bar_id
with_bar.id
end
end
class Item < ActiveRecord::Base
belongs_to :item_type
belongs_to :foo
scope :with_bar_types, -> { where(item_type_id: ItemType.with_bar_id) }
end
class Foo < ActiveRecord::Base
has_many :items
# automatically sets the foo_id, no need to mention explicitly
# the chained with_bar_types automatically sets the item_type_id to ItemType.with_bar_id
def build_item
self.items.with_bar_types.new
end
end
# Controller
class ItemsController
def update
@item.update(item_type_id: ItemType.with_bar_id)
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With