Skip to content

Instantly share code, notes, and snippets.

@adis-io
Created September 15, 2020 08:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adis-io/b8e34eb1da6c839ec23cae242f806b01 to your computer and use it in GitHub Desktop.
Save adis-io/b8e34eb1da6c839ec23cae242f806b01 to your computer and use it in GitHub Desktop.
Rails models with Wordpress DB
class Category < Taxonomy
def self.sti_name
"category"
end
end
class Entity < ActiveRecord::Base
include WpHelper
self.table_name = "#{wp_db_name}.main_posts"
self.primary_key = 'ID'
self.inheritance_column = :post_type
has_many :post_metas
has_many :term_relationships, :foreign_key => 'object_id'
has_many :term_taxonomies, through: :term_relationships
alias_attribute :id, :ID
alias_attribute :slug, :post_name
alias_attribute :title, :post_title
alias_attribute :content, :post_content
alias_attribute :status, :post_status
alias_attribute :published_at, :post_date
alias_attribute :updated_at, :post_modified
alias_attribute :excerpt, :post_excerpt
def self.find_sti_class(type_name)
self
end
end
require 'bcrypt'
module Passwordable
extend ActiveSupport::Concern
module ClassMethods
def has_password(options = {})
begin
require "phpass"
rescue LoadError
$stderr.puts "You don't have phpass-ruby installed in your application. Please add it to your Gemfile and run bundle install"
raise
end
begin
require "rbpass"
rescue LoadError
$stderr.puts "You don't have rbpass installed in your application. Please add it to your Gemfile and run bundle install"
raise
end
include InstanceMethodsOnActivation
if options.fetch(:validations, true)
include ActiveModel::Validations
# This ensures the model has a password by checking whether the password_digest
# is present, so that this works with both new and existing records. However,
# when there is an error, the message is added to the password attribute instead
# so that the error message will make sense to the end-user.
validate do |record|
record.errors.add(:password, :blank) unless record.password_digest.present?
end
validates_length_of :password, maximum: 4096
validates_confirmation_of :password, allow_blank: true
end
end
end
module InstanceMethodsOnActivation
# Returns +self+ if the password is correct, otherwise +false+.
#
# class User < ActiveRecord::Base
# has_password validations: false
# end
#
# user = User.new(name: 'david', password: 'asdasd')
# user.save
# user.authenticate('qweqwe') # => false
# user.authenticate('asdasd') # => user
def authenticate unencrypted_password
RbPass::PasswordHasher.new(8, false).check(unencrypted_password, password_digest) && self
end
attr_reader :password
# Encrypts the password into the +password_digest+ attribute, only if the
# new password is not empty.
#
# class User < ActiveRecord::Base
# has_secure_password validations: false
# end
#
# user = User.new
# user.password = nil
# user.password_digest # => nil
# user.password = 'mUc3m00RsqyRe'
# user.password_digest # => "$2a$10$4LEA7r4YmNHtvlAvHhsYAeZmk/xeUVtMTYqwIvYY76EW5GUqDiP4."
def password= unencrypted_password
if unencrypted_password.nil?
self.password_digest = nil
elsif !unencrypted_password.empty?
@password = unencrypted_password
self.password_digest = Phpass.new.hash(password)
end
end
def password_confirmation= unencrypted_password
@password_confirmation = unencrypted_password
end
end
end
class Post < Entity
def self.sti_name
"post"
end
scope :published, -> { where(status: 'publish') }
scope :sort_by_newest, -> { order(published_at: :desc) }
scope :search_import, -> { with_taxonomies }
before_create :create_slug
before_validation :create_excerpt
before_create do
self.to_ping = ""
self.pinged = ""
self.post_content_filtered = ""
self.published_at = 1.day.from_now
end
has_many :taxonomy_posts, :foreign_key => 'object_id'
has_many :taxonomies, through: :taxonomy_posts
# Primary category
has_one :primary_category_pivot
has_one :primary_category, through: :primary_category_pivot, source: :category
# Featured image
has_one :featured_image_pivot
has_one :featured_image, through: :featured_image_pivot
has_many :activities, as: :subject
validates_presence_of :post_title, :title, :content
belongs_to :author, :foreign_key => 'post_author'
# Use scope#with_featured to use featured_images
def featured_image
image = (super rescue nil) || NullFeaturedImage.new
image.extend FeaturedImageExtension
image
end
def author
(super rescue nil) || NullAuthor.new
end
def categories
taxonomies.select { |t| t.taxonomy == 'category' }
end
def tags
taxonomies.select { |t| t.taxonomy == 'post_tag' }
end
def primary_or_first_category
primary_category || categories.first || NullCategory.new
end
def published?
self.status == "publish"
end
def formatted_title
self.title.gsub('--', '—')
end
def self.with_featured
includes(:featured_image)
end
def self.with_taxonomies
includes(taxonomies: :term)
end
private
def create_slug
slugged_title = self.title.parameterize
n = 1
self.slug = loop do
slugged_title = slugged_title + "-" + n.to_s if n > 1
break slugged_title unless Post.exists?(slug: slugged_title)
n += 1
end
end
def create_excerpt
self.excerpt = begin
sanitized = ActionController::Base.helpers.sanitize(self.content)
ActionController::Base.helpers.truncate(sanitized, length: 150)
end
end
end
class PrimaryCategoryPivot < ActiveRecord::Base
include WpHelper
self.table_name = "#{wp_db_name}.main_postmeta"
self.primary_key = 'meta_id'
default_scope { where(meta_key: 'primary_category') }
alias_attribute :term_id, :meta_value
belongs_to :post
belongs_to :category, foreign_key: :meta_value, primary_key: :term_id
end
class Tag < Taxonomy
def self.sti_name
"post_tag"
end
end
class Taxonomy < ActiveRecord::Base
include WpHelper
self.table_name = "#{wp_db_name}.main_term_taxonomy"
self.primary_key = 'term_taxonomy_id'
has_many :taxonomy_posts, :foreign_key => 'term_taxonomy_id'
has_many :posts, through: :taxonomy_posts, source: :post
belongs_to :term
self.inheritance_column = :taxonomy
delegate :name, to: :term
delegate :slug, to: :term
alias_attribute :id, :term_taxonomy_id
def self.find_sti_class(type_name)
self
end
['category', 'post_tag'].each do |slug|
define_singleton_method("only_#{slug.pluralize}") do
where(taxonomy: slug)
end
end
def self.with_term
includes(:term)
end
end
class TaxonomyPost < ActiveRecord::Base
include WpHelper
self.table_name = "#{wp_db_name}.main_term_relationships"
default_scope { order('object_id') }
belongs_to :post, :foreign_key => 'object_id'
belongs_to :taxonomy, :foreign_key => 'term_taxonomy_id'
end
class Term < ActiveRecord::Base
include WpHelper
self.table_name = "#{wp_db_name}.main_terms"
self.primary_key = 'term_id'
has_one :taxonomy, foreign_key: 'term_id'
end
class User < ActiveRecord::Base
include WpHelper
include ActiveModel::Validations
include Passwordable
has_password
self.table_name = "#{wp_db_name}.main_users"
self.primary_key = 'ID'
has_many :user_metas
alias_attribute :id , :ID
alias_attribute :email , :user_email
alias_attribute :login , :user_login
alias_attribute :registered_at , :user_registered
alias_attribute :name , :display_name
alias_attribute :password_digest , :user_pass
before_validation :set_user_nicename , on: :create
before_validation :set_time , on: :create
validates_presence_of :user_login, :user_email, :user_registered, :display_name
validates_uniqueness_of :user_login, :user_email
def avatar
avatar = get_custom_avatar
if avatar.blank?
hash = Digest::MD5.hexdigest(self.email)
avatar = "http://www.gravatar.com/avatar/#{hash}?s=100"
end
avatar
end
private
def set_user_nicename
user_nicename = user_login
end
def set_time
self.user_registered ||= Time.now
end
end
class UserMeta < ActiveRecord::Base
include WpHelper
self.table_name = "#{wp_db_name}.main_usermeta"
self.primary_key = 'umeta_id'
belongs_to :user
end
module WpHelper
extend ActiveSupport::Concern
included do
establish_connection(:"#{wp_db}")
end
module ClassMethods
def wp_db
"wp_#{Rails.env}"
end
def wp_db_name
Rails.configuration.database_configuration["#{wp_db}"]['database']
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment