Skip to content

Instantly share code, notes, and snippets.

@8vius
Created April 8, 2015 17:56
Show Gist options
  • Save 8vius/a33ab9a4470178cdfe9b to your computer and use it in GitHub Desktop.
Save 8vius/a33ab9a4470178cdfe9b to your computer and use it in GitHub Desktop.
class Yum < ActiveRecord::Base
default_scope -> { order('yums.created_at DESC') }
has_many :mentions, as: :trackable, dependent: :destroy
has_many :reports, as: :trackable
belongs_to :user
has_many :likes, dependent: :destroy
has_many :likers, through: :likes, source: :user
has_many :categories, through: :venue, source: :categories
belongs_to :venue
has_and_belongs_to_many :tags
has_many :comment_tags, through: :comments, source: :tags
has_many :comments, dependent: :destroy
has_attached_file :image, styles: {
medium: "640x640>",
large: "1280x1280>" ,
thumb: "208x208>"
},
default_url: "/images/missing_avatar.png"
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
validates_attachment_presence :image
validates :name, presence: true
validates :venue_id, presence: true
validates :user_id, presence: true
before_save do
create_tags
end
scope :user, -> (user_id) { where user_id: user_id }
scope :venue, -> (venue_id) { where venue_id: venue_id }
scope :tag, -> (tag_id) { joins(:tags).where(tags: { id: tag_id }) }
scope :after, -> (after) { where("yums.id > :after", after: after) }
scope :before, -> (before) { where("yums.id < :before", before: before) }
scope :random, -> (limit) { unscoped.order("RANDOM()").limit(limit) }
include PgSearch
pg_search_scope :search, against: [:name, :caption],
using: {
tsearch: {
dictionary: "english",
prefix: true
}
},
associated_against: {
venue: [:name],
categories: [:name],
tags: [:content]
}
pg_search_scope :search_by_tags,
associated_against: {
tags: [:content],
comment_tags: [:content]
}
pg_search_scope :search_by_name, against: [:name]
# Class method to get all the Yums created by Users the specified User follows
#
# ==== Parameters
#
# * +user+ - The user to get his followed users Yums from
def self.from_users_followed_by(user)
followed_user_ids = "SELECT followed_id FROM relationships WHERE follower_id = :user_id"
where("user_id IN (#{followed_user_ids}) OR user_id = :user_id", user_id: user.id)
end
# Retrieves Yums in Venues near a provided latitude a longitude
#
# ==== Parameters
#
# * +ll+ - String with separated latitude and longitude in
def self.near(ll)
lat, lng = ll.split(',')
location_ids = Location.near([lat, lng], 5, units: :km).map(&:id)
venue_ids = Venue.where("location_id IN (?)", location_ids).map(&:id)
where("venue_id IN (?)", venue_ids)
end
# Retrieves Yums with a specified tag
#
# ==== Parameters
#
# * +tag_id+ - The ID of the tag associated to the desired Yums
def self.with_tag(tag_id)
where("tags.id = :tag_id", tag_id: tag_id).joins(:tags)
end
# Retrieves the 20 most liked Yums
def self.top_yums
unscoped
.select("yums.*, COUNT(yum_id) as like_count")
.joins("LEFT JOIN likes AS likes ON likes.yum_id = yums.id")
.group("yums.id")
.order("like_count DESC")
.limit(20)
end
# Called before the Comment is saved to extract the tags present
# in the content of the Comment.
#
# Tags start with a # so a regex is used to search for words starting
# with the symbol which are then associated to the Comment and saved
#
# ==== Examples
#
# # For a comment with the content "This is an #example for #tags"
# # Tags with name +example+ and +tags+ will be created
def create_tags
tags = caption.scan(/\#[[:alnum:]]+/)
for tag in tags
tag = tag.sub("#", "")
if found_tag = Tag.find_by_content(tag.downcase)
self.tags << found_tag
else
self.tags.build(content: tag)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment