Forum: Ruby on Rails Add functionality to multiple models?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
rv d. (Guest)
on 2007-05-07 12:35
Hello,

I'm working on a system for managing multiple different items, let's say
articles and pictures. All these items can be published and unpublished.
They have a published_at datetime field that is nil in unpublished
state, and filled out in published state.

This is the code that I use in the models:

class SomeModel < ActiveRecord::Base
  attr_protected :published_at

  def published?
    !published_at.nil?
  end

  def pending?
    !published? || Time.now < published_at
  end

  def status
    pending? ? :pending : :published
  end

  def publish
    self.published_at = Time.now if self.pending?
  end

  def unpublish
    self.published_at = nil
  end

end



But, I want to keep it DRY, and I do not want to add these lines to any
model that should be publishable. I tried to create a
publishable_item.rb model class and to inherit from that, but in this
case Rails will look for a publishable_items table.

So I'm looking forward to your suggestions.
Trochalakis C. (Guest)
on 2007-05-07 13:55
(Received via mailing list)
On May 7, 11:35 am, rv dh <removed_email_address@domain.invalid> wrote:
> [..]
> end
>
> But, I want to keep it DRY, and I do not want to add these lines to any
> model that should be publishable. I tried to create a
> publishable_item.rb model class and to inherit from that, but in this
> case Rails will look for a publishable_items table.

Try using a mixin (module).

http://www.rubycentral.com/book/tut_modules.html
rv d. (Guest)
on 2007-05-07 18:42
Trochalakis C. wrote:
> Try using a mixin (module).
>
> http://www.rubycentral.com/book/tut_modules.html

Thanks, that did it. For anyone interested, the mixin looks like this
(model must have attribute published_at):

In any model:
  include PublishableSystem
  acts_as_publishable


#lib/publishable_system.rb:
module PublishableSystem
  # an die Klasse anhängen, die diese Erweiterung aufruft
  def self.included(klass)
    klass.extend ClassMethods
  end

  module ClassMethods
    def acts_as_publishable
      include PublishableSystem::InstanceMethods
      attr_protected :published_at
    end
  end

  module InstanceMethods
    def published?
      !published_at.nil?
    end

    def pending?
      !published? || Time.now < published_at
    end

    def status
      pending? ? :pending : :published
    end

    def publish
      self.published_at = Time.now if self.pending?
    end

    def unpublish
      self.published_at = nil
    end
  end
end
This topic is locked and can not be replied to.