aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/models/topic.rb
blob: 77101090f249a3ed3585c7b2bb0bb862458a708e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
# frozen_string_literal: true

class Topic < ActiveRecord::Base
  scope :base, -> { all }
  scope :written_before, lambda { |time|
    if time
      where "written_on < ?", time
    end
  }
  scope :approved, -> { where(approved: true) }
  scope :rejected, -> { where(approved: false) }

  scope :scope_with_lambda, lambda { all }

  scope :by_lifo, -> { where(author_name: "lifo") }
  scope :replied, -> { where "replies_count > 0" }

  scope "approved_as_string", -> { where(approved: true) }
  scope :anonymous_extension, -> { } do
    def one
      1
    end
  end

  scope :with_object, Class.new(Struct.new(:klass)) {
    def call
      klass.where(approved: true)
    end
  }.new(self)

  module NamedExtension
    def two
      2
    end
  end

  has_many :replies, dependent: :destroy, foreign_key: "parent_id", autosave: true
  has_many :approved_replies, -> { approved }, class_name: "Reply", foreign_key: "parent_id", counter_cache: "replies_count"

  has_many :unique_replies, dependent: :destroy, foreign_key: "parent_id"
  has_many :silly_unique_replies, dependent: :destroy, foreign_key: "parent_id"

  serialize :content

  before_create  :default_written_on
  before_destroy :destroy_children

  def parent
    Topic.find(parent_id)
  end

  # trivial method for testing Array#to_xml with :methods
  def topic_id
    id
  end

  alias_attribute :heading, :title

  before_validation :before_validation_for_transaction
  before_save :before_save_for_transaction
  before_destroy :before_destroy_for_transaction

  after_save :after_save_for_transaction
  after_create :after_create_for_transaction

  after_initialize :set_email_address

  attr_accessor :change_approved_before_save
  before_save :change_approved_callback

  class_attribute :after_initialize_called
  after_initialize do
    self.class.after_initialize_called = true
  end

  attr_accessor :after_touch_called

  after_initialize do
    self.after_touch_called = 0
  end

  after_touch do
    self.after_touch_called += 1
  end

  def approved=(val)
    @custom_approved = val
    write_attribute(:approved, val)
  end

  def self.nested_scoping(scope)
    scope.base
  end

  private

    def default_written_on
      self.written_on = Time.now unless attribute_present?("written_on")
    end

    def destroy_children
      self.class.delete_by(parent_id: id)
    end

    def set_email_address
      unless persisted? || will_save_change_to_author_email_address?
        self.author_email_address = "test@test.com"
      end
    end

    def before_validation_for_transaction; end
    def before_save_for_transaction; end
    def before_destroy_for_transaction; end
    def after_save_for_transaction; end
    def after_create_for_transaction; end

    def change_approved_callback
      self.approved = change_approved_before_save unless change_approved_before_save.nil?
    end
end

class DefaultRejectedTopic < Topic
  default_scope -> { where(approved: false) }
end

class BlankTopic < Topic
  # declared here to make sure that dynamic finder with a bang can find a model that responds to `blank?`
  def blank?
    true
  end
end

class TitlePrimaryKeyTopic < Topic
  self.primary_key = :title
end

module Web
  class Topic < ActiveRecord::Base
    has_many :replies, dependent: :destroy, foreign_key: "parent_id", class_name: "Web::Reply"
  end
end