Skip to content

Instantly share code, notes, and snippets.

@kaspernj
Created January 26, 2021 19:48
Show Gist options
  • Save kaspernj/708c62f8c9d435353dc9b6f146f1851a to your computer and use it in GitHub Desktop.
Save kaspernj/708c62f8c9d435353dc9b6f146f1851a to your computer and use it in GitHub Desktop.
begin
require 'bundler/inline'
rescue LoadError => e
$stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
raise e
end
gemfile(true) do
source 'https://rubygems.org'
gem 'rails', '6.1.1' # use correct rails version
gem 'activemodel'
gem 'cancancan', path: "./" # use correct cancancan version
gem 'mysql2' # use another DB if necessary
gem 'mysql-binuuid-rails', require: false
gem 'pry-rails'
end
require 'active_record'
require 'active_model'
require 'cancancan'
require 'cancan/model_adapters/active_record_adapter'
require 'cancan/model_adapters/active_record_4_adapter'
require 'minitest/autorun'
require 'logger'
require 'mysql-binuuid-rails'
require_relative 'lib/cancan/model_adapters/active_record_5_adapter'
require_relative 'lib/cancan/model_adapters/sti_normalizer'
require_relative 'lib/cancan/model_adapters/conditions_normalizer'
require_relative 'lib/cancan/model_adapters/conditions_extractor'
# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(
adapter: 'mysql2',
database: 'cancancan',
host: 'mysql',
username: 'root',
password: 'password'
)
ActiveRecord::Base.logger = Logger.new(STDOUT)
# create your tables here
ActiveRecord::Schema.define do
drop_table :books if table_exists? :books
drop_table :authors if table_exists? :authors
drop_table :users if table_exists? :users
create_table :users, id: {limit: 16, type: :binary}, force: true do |t|
t.string :name
end
create_table :authors, id: {limit: 16, type: :binary}, force: true do |t|
t.references :user, limit: 16, type: :binary
end
create_table :books, id: {limit: 16, type: :binary}, force: true do |t|
t.references :author, limit: 16, type: :binary
end
add_foreign_key :books, :authors
add_foreign_key :authors, :users
end
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
attribute :id, MySQLBinUUID::Type.new
before_validation do
self.id = SecureRandom.uuid if new_record? && !id?
end
# Hack to automatically do the UUID stuff for all relationships
def self.belongs_to(relationship_name, *args, &blk)
super
attribute :"#{relationship_name}_id", MySQLBinUUID::Type.new
end
end
class Author < ApplicationRecord
belongs_to :user
has_many :books
end
class Book < ApplicationRecord
belongs_to :author
end
class User < ApplicationRecord
has_many :authors
end
class Ability
include CanCan::Ability
def initialize(user)
can :read, Book, author: {user_id: user.id}
end
end
class BugTest < Minitest::Test
def test_bug
user1 = User.create!
user2 = User.create!
author1 = Author.create!(user: user1)
author2 = Author.create!(user: user2)
book1 = Book.create!(author: author1)
book2 = Book.create!(author: author2)
ability = Ability.new(user1)
books = Book.accessible_by(ability, :read).count
puts "SQL: #{Book.accessible_by(ability, :read).to_sql}"
assert_equal 1, books
end
end
# class TestApp < Rails::Application
# config.root = File.dirname(__FILE__)
# config.session_store :cookie_store, key: "cookie_store_key"
# secrets.secret_token = "secret_token"
# secrets.secret_key_base = "secret_key_base"
# config.logger = Logger.new($stdout)
# Rails.logger = config.logger
# routes.draw do
# resources :libraries do
# resources :books
# end
# end
# end
# class ExampleController < ActionController::Base
# include CanCan::ControllerAdditions
# end
# class ExampleControllerTest < ActionController::TestCase
# setup do
# @controller = ExampleController.new
# @routes = Rails.application.routes
# end
# def test_action
# # ...
# end
# end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment