Module: Publishable::ClassMethods

Defined in:
lib/publishable.rb

Overview

Define scopes and methods for querying and manipulating Publishables.

Query scopes added to publishable models collapse

Instance methods added to publishable models collapse

Instance Method Summary collapse

Class Method Details

.publishedObject

Query scope added to publishables that can be used to find published records. For Date/DateTime publishables, you can pass a specific date on which the results should be published.

Examples:

Find only records that are currently published

published_posts = Post.published

Find only records that will be published in two days

future_posts = Post.published(Date.current + 2.days)

Parameters:

  • when (Date, Time, nil)

    Specify a date/time for Date/DateTime publishables - defaults to the current date/time



# File 'lib/publishable.rb', line 194

.recentObject

Query scope added to publishables that can be used to lookup records which are currently published. The results are returned in descending order based on the published date/time.

Examples:

Get the 10 most recently-published records

recent_posts = Post.recent(10)

Parameters:

  • how_many (Integer, nil)

    Specify how many records to return



# File 'lib/publishable.rb', line 212

.unpublishedObject

Query scope added to publishables that can be used find records which are not published. For Date/DateTime publishables, you can pass a specific date on which the results should not have been published.

Examples:

Find only records that are not currently published

unpublished_posts = Post.unpublished

Parameters:

  • when (Date, Time, nil)

    Specify a date/time for Date/DateTime publishables - defaults to the current date/time



# File 'lib/publishable.rb', line 204

.upcomingObject

Query scope added to publishables that can be used to lookup records which are not currently published. The results are returned in ascending order based on the published date/time.

Examples:

Get all posts that will be published in the future

upcoming_posts = Post.upcoming

Parameters:

  • how_many (Integer, nil)

    Specify how many records to return



# File 'lib/publishable.rb', line 220

Instance Method Details

#publishObject

Publish this object. For a Boolean publish field, the field is set to true; for a Date/DateTime field, the field is set to the given Date/Time or to the current date/time.

Parameters:

  • when (Date, Time, nil)

    For Date/DateTime publishables, a date/time can be passed to specify when the record will be published. Defaults to Date.current or Time.now.



# File 'lib/publishable.rb', line 246

#publish!Object

Publish this object, then immediately save it to the database.

Parameters:

  • when (Date, Time, nil)


# File 'lib/publishable.rb', line 253

#publishable(options = {}) ⇒ Object

DSL method to link this behavior into your model. In your ActiveRecord model class, add publishable to include the scopes and methods for publishable objects.

Examples:

class Post < ActiveRecord::Base
  publishable
end

Parameters:

  • options (Hash) (defaults to: {})

    The publishable options.

Options Hash (options):

  • :on (String, Symbol) — default: :publishable

    The name of the publishable column on the model.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/publishable.rb', line 39

def publishable(options = {})
  return unless table_exists?
  column_name = (options[:on] || :published).to_sym
  # silently ignore a missing column - since bombing on a missing column can make re-running migrations very hard
  return unless self.columns_hash[column_name.to_s].present?
  column_type = self.columns_hash[column_name.to_s].type

  if respond_to?(:scope)

    # define published/unpublished scope
    case column_type
      when :date
        scope :published, lambda { |*args|
          on_date = args[0] || Date.current
          where(arel_table[column_name].not_eq(nil)).where(arel_table[column_name].lteq(on_date))
        }

        scope :unpublished, lambda { |*args|
          on_date = args[0] || Date.current
          where(arel_table[column_name].not_eq(nil)).where(arel_table[column_name].gt(on_date))
        }

      when :datetime
        scope :published, lambda { |*args|
          at_time = args[0] || Time.now
          where(arel_table[column_name].not_eq(nil)).where(arel_table[column_name].lteq(at_time.utc))
        }

        scope :unpublished, lambda { |*args|
          at_time = args[0] || Time.now
          where(arel_table[column_name].not_eq(nil)).where(arel_table[column_name].gt(at_time.utc))
        }

      when :boolean
        scope :published, lambda {
          where(column_name => true)
        }

        scope :unpublished, lambda {
          where(column_name => false)
        }

      else
        raise ActiveRecord::ConfigurationError, "Invalid column_type #{column_type} for Publishable column on model #{self.name}"
    end

    # define recent/upcoming scopes
    if [:date, :datetime].include? column_type
      scope :recent, lambda { |*args|
        how_many = args[0] || nil
        col_name = arel_table[column_name].name
        published.limit(how_many).order("#{col_name} DESC")
      }
      scope :upcoming, lambda { |*args|
        how_many = args[0] || nil
        col_name = arel_table[column_name].name
        unpublished.limit(how_many).order("#{col_name} ASC")
      }
    end

  end

  case column_type
    when :datetime
      class_eval <<-EVIL, __FILE__, __LINE__ + 1
        def published?(_when = Time.now)
          #{column_name} ? #{column_name} <= _when : false
        end

        def unpublished?(_when = Time.now)
          !published?(_when)
        end

        def publish(_when = Time.now)
          self.#{column_name} = _when unless published?(_when)
        end

        def publish!(_when = Time.now)
          publish(_when) && (!respond_to?(:save) || save)
        end

        def unpublish()
          self.#{column_name} = nil
          true
        end

        def unpublish!()
          unpublish() && (!respond_to?(:save) || save)
        end
      EVIL

    when :date
      class_eval <<-EVIL, __FILE__, __LINE__ + 1
        def published?(_when = Date.current)
          #{column_name} ? #{column_name} <= _when : false
        end

        def unpublished?(_when = Date.current)
          !published?(_when)
        end

        def publish(_when = Date.current)
          self.#{column_name} = _when unless published?(_when)
        end

        def publish!(_when = Date.current)
          publish(_when) && (!respond_to?(:save) || save)
        end

        def unpublish()
          self.#{column_name} = nil
        end

        def unpublish!()
          unpublish() && (!respond_to?(:save) || save)
        end
      EVIL

    when :boolean
      class_eval <<-EVIL, __FILE__, __LINE__ + 1
        def published?()
          #{column_name}
        end

        def unpublished?()
          !published?()
        end

        def publish()
          self.#{column_name} = true
        end

        def publish!()
          publish()
          save if respond_to?(:save)
        end

        def unpublish()
          self.#{column_name} = false
        end

        def unpublish!()
          unpublish()
          save if respond_to?(:save)
        end
      EVIL

    else
      raise ActiveRecord::ConfigurationError, "Invalid column_type #{column_type} for Publishable column on model #{self.name}"
  end

end

#published?Boolean

Is this object published?

Parameters:

  • when (Date, Time, nil)

    For Date/DateTime publishables, a date/time can be passed to determine if the object was / will be published on the given date.

Returns:

  • (Boolean)

    true if published, false if not published.



# File 'lib/publishable.rb', line 232

#unpublishObject

Un-publish this object, i.e. set it to not be published. For a Boolean publish field, the field is set to false; for a Date/DateTime field, the field is cleared.



# File 'lib/publishable.rb', line 258

#unpublish!Object

Un-publish this object, then immediately save it to the database.



# File 'lib/publishable.rb', line 263

#unpublished?Boolean

Is this object not published?

Parameters:

  • when (Date, Time, nil)

    For Date/DateTime publishables, a date/time can be passed to determine if the object was not / will not be published on the given date.

Returns:

  • (Boolean)

    false if published, true if not published.



# File 'lib/publishable.rb', line 239