简体   繁体   中英

Only one instance of a Model in Rails

I'm working on my first Rails app. It needs to store some information about a single advertisement that will appear on every page. The admin just needs to be able to set the URL, Title, and an image. Obviously, I only need one instance of this ad object.

I created a model that inherits from ActiveRecod::Base, but that seems like the wrong thing to do, since it is configured to save multiple ads in a database table.

What's the best way for me to do this? What should the model and controller look like?

Thanks in advance, Avi

Well, if you are going to store the information (URL, Title, image) in the database, I think having it inheriting from AR is the right thing to do. If they are going to do this through any sort of front-end, I think this is your best option.

Why not allow for multiple advertisements, but only one of them can be published at a time? That way, you can also have a history of the advertisements—I don't know how important that part is, but it might prove interesting down the line.

A better way would be adding a validation that checks if one record entry already exists.

Inside your model:

validate :check_record, on: :create #please not that validate in this case is singular

def check_record
 if Ad.all.count === 1
   errors[:base] << "You can only have one active advertisement"
 end
end

I agree. If you're completely sure it's static, then it doesn't even need to be stored in the database. If it does change, Rails will give you created_at and updated_at pretty much for free, so getting the most recently created / updated is one simple way to approach displaying what's current.

I would suggest that you continue using ActiveRecord but that you add a boolean attribute that determines which of the many advertisement records is the active one. I have called this field active within the following example.

You can then validate within the model that a maximum of one record is active. The validation of the active attribute should succeed under any of the following conditions

  1. The active attribute is set to false
  2. There are 0 records with an active value of true.
  3. The current record already has the attribute set to true in the database.

The following class should meet your needs

class Ad < ActiveRecord::Base

  named_scope :has_active, :conditions => {:active => true}

  def validate
    errors.add_to_base "You can only have one active advertisement" 
        unless self.active_flag_valid?
  end

  def active_flag_valid?
    self.active == false || 
    Ad.has_active.size == 0 || 
    ( Ad.has_active.size == 1 && !self.active_changed?)
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM