Skip to content

Instantly share code, notes, and snippets.

@mrbrdo
Last active November 4, 2015 16:35
Show Gist options
  • Save mrbrdo/56da0dd984b4191a7273 to your computer and use it in GitHub Desktop.
Save mrbrdo/56da0dd984b4191a7273 to your computer and use it in GitHub Desktop.
# Sequel assoc_ids / assoc_ids=
module SequelAssociationIds
def one_to_many(name, *args, &block)
super
create_ids_accessor(name)
end
def many_to_many(name, *args, &block)
super
create_ids_accessor(name)
end
def create_ids_accessor(name)
name = name.to_s.singularize
define_method :"#{name}_ids" do
if new?
[]
else
assoc = name[/\A(.+)_ids\z/, 1]
send("#{assoc.pluralize}_dataset").select_map(:id)
end
end
define_method :"#{name}_ids=" do |ids|
after_save_hook do
ids.select(&:present?).map(&:to_i).each do |id|
send("add_#{name}", id)
end
end
end
end
end
Sequel::Model.singleton_class.send :prepend, SequelAssociationIds
# Only uses ActiveRecord::Base to find models
module Administrate
module Generators
module ActiveRecord
Base = ::Sequel::Model
end
end
end
# Administrate monkey-patches for Sequel
module Administrate
Order.class_eval do
def apply(relation)
if relation.model.columns.include?(attribute.try!(:to_sym))
relation.order(Sequel.send(direction, attribute.to_sym))
else
relation
end
end
end
ApplicationController.class_eval do
def index
search_term = params[:search].to_s.strip
resources = Administrate::Search.new(resource_resolver, search_term).run
resources = order.apply(resources)
resources = resources.limit(nil).paginate(params[:page], records_per_page)
page = Administrate::Page::Collection.new(dashboard, order: order)
render locals: {
resources: resources,
search_term: search_term,
page: page,
}
end
end
# Wrapper object to make Sequel model classes seem like ActiveRecord to Administrate
class SequelModelProxy < SimpleDelegator
def find(id)
self[id]
end
def all
dataset
end
def reflections
association_reflections.each_with_object({}) do |(k,v), a|
obj = OpenStruct.new(
has_one?: v[:type] == :one_to_one,
collection?: v[:type].in?([:one_to_many, :many_to_many]),
polymorphic?: false,
class_name: v[:class_name]
)
a[k.to_s] = obj if obj.has_one? || obj.collection?
end
end
def attribute_names
columns.map(&:to_s)
end
def column_types
obj = Hash.new(OpenStruct.new)
db_schema.each_with_object(obj) do |(k,v), a|
a[k.to_s] = OpenStruct.new(type: v[:type] || v[:db_type].to_sym || :unknown)
end
end
end
# Wrap Sequel models in the above wrapper (this patch only takes effect in the Administrate module namespace)
module Object
def self.const_get(name)
obj = ::Object.const_get(name)
if obj.ancestors.include?(Sequel::Model)
SequelModelProxy.new(obj)
else
obj
end
end
end
end
# Kaminari & pagination stuff based on https://gist.github.com/citrus/1602209
module Kaminari
module Sequel
def self.included(base)
base.class_eval do
alias :num_pages :page_count
alias :total_pages :page_count
alias :limit_value :page_size
end
end
end
end
Sequel.extension :pagination
Sequel::Dataset::Pagination.send(:include, Kaminari::Sequel)
Sequel::DatasetPagination
module Sequel::DatasetPagination
def paginate_with_safe_page(page_no, page_size, record_count=nil)
page_no = page_no.to_i
page_no = page_no == 0 ? 1 : page_no
paginate_without_safe_page(page_no, page_size, record_count)
end
alias_method_chain :paginate, :safe_page
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment