0

I have a Ruby on Rails application that uses rails_admin (https://github.com/sferik/rails_admin) as the backend.

I have a model called banner, so a table in the database called banners. The admin can create as many banners as he can and can also delete them. But I want to fix the number of banners in 3. I want to have 3 banners (already created) and I want the admin cannot create nor destroy any banners.

Could someone help me?

Thanks!

rafaame
  • 822
  • 2
  • 12
  • 22

3 Answers3

0
 class Thing < ActiveRecord::Base
   has_many :banners
 end

app/controllers/things_controller.rb

 def create
   @thing = Thing.new
   @thing.banners << Banner.new(:name=>'Banner 1',....)
   @thing.banners << Banner.new(:name=>'Banner 2',....)
   @thing.banners << Banner.new(:name=>'Banner 3',....)
   @thing.save
 end

Now so long as nowhere else to you call @thing.banners << , you are guaranteed that any thing will always have three banners.

RadBrad
  • 7,234
  • 2
  • 24
  • 17
0

Validations to the rescue:

class Thing < Active Record::Base
  has_many :banners

  validate :banner_count

  private
    def banner_count
      errors.add(:base, "Banner count must be 3") unless self.banners.count == 3
    end
end
boulder
  • 3,256
  • 15
  • 21
0

@RadBrad makes the point that you could use has_many on another model that represents the set of three banners. Maybe could call it BannerSet or similar. You could either create the three at once like he said, or in the BannerSet validation, you could ensure there are only 3 banners associated.

You could also have even 3 attributes (columns) on the BannerSet model that would have the 3 ids of the banners. If you are sure it will always be 3 banners, then that may be a fine design also.

But, here is how you'd do it if you just had a controller for Banner, which wouldn't be the best way, as you'll see.

First, you could possibly use declarative authorization in the controller:

authorization do
  has_permission_on :banners, :to => [:new, :create] do
    Banner.count < 3
  end
end

To ensure that you still can't add a banner even if it was added after you got to the create screen to add it, also add a validation to the Banner model:

before_create :validate_max_banners

def validate_max_banners
  errors.add_to_base("Only 3 banners are allowed.") if Banner.count == 3
  errors.empty?
end

Neither will totally ensure you can only have 3 rows in that table though. To do that, you'd need a trigger or similar on the DB side, as described in this q&a. But, for a basic solution, that might be fine.

Note that even though RailsAdmin can be configured and customized pretty easily (see its wiki for documentation), I'd also consider using ActiveAdmin, if you need a lot more customization.

Community
  • 1
  • 1
Gary S. Weaver
  • 7,966
  • 4
  • 37
  • 61