I have a site in rails and want to have site-wide settings. One part of my app can notify the admin by SMS if a specific event happens. This is an example of a feature that
I will put a few remarks to the previous answers:
id
field. Since we should have id
field in a Rails app anyway, it's a good tradeoffIf we apply these modifications, the solution becomes very easy:
# migration
create_table :settings, id: false do |t|
t.integer :id, null: false, primary_key: true, default: 1, index: {unique: true}
t.integer :setting1
t.integer :setting2
...
end
# model
class Settings < ApplicationRecord
def self.instance
first_or_create!(...)
end
end
I assume to use inheriting column type
with uniq constraint.
# miragtion
class CreateSingletonRecords < ActiveRecord::Migration[5.2]
create_table :balance_holders do |t|
t.string :type
t.index :type, unique: true
t.timestamps
end
end
several methods in you parent class:
class SingletonRecord < ApplicationRecord
class << self
def instance
@singleton__instance__
end
def load_record(params = {})
@singleton__instance__ = find_or_create_by!(params)
end
end
load_record
validates :type, uniqueness: true
end
After it you can forever use single record for singleton model class. Your instance will be loaded or created one time durring model class loaded.
I am not sure I'd waste the database/ActiveRecord/Model overhead for such a basic need. This data is relatively static (I am assuming) and on the fly calculations aren't necessary (including database lookups).
Having said that, I'd recommend you define a YAML file with your site-wide settings and define an initializer file that loads the settings into a constant. You won't have nearly as many of the unnecessary moving parts.
There is no reason that data couldn't just sit in memory and save you a ton of complexity. Constants are available everywhere, and they don't need to be initialized or instantiated. If its absolutely critical that you utilize a class as a singleton, I'd recommend doing these two things:
I know this is an old thread, but I just needed the same thing and found out that there's a gem for this: acts_as_singleton.
Installation instructions are for Rails 2, but it works great with Rails 3 too.
Using has_many :contacts
doesn't mean you need a model. has_many
does some magic, but in the end it's just adds some method with a specified contract. There's no reason why you can't implement those methods (or some subset that you need) to make your model behave like it has_many :contacts
yet not actually use an ActiveRecord model (or model at all) for Contact.
You can do it like this:
class Config < ApplicationRecord
def self.instance
Config.first || Config.create!
end
end