Coder Social home page Coder Social logo

where-or's Introduction

Where Or

Where or function backport from Rails 5 for Rails 4.2

Confirm works from Rails 4.2.3 to 4.2.6, including for preloading, higher version may also works. Please create issue with your experience.

Gem Version

Installation:

gem 'where-or'

Usage

post = Post.where('id = 1').or(Post.where('id = 2'))

Declare of original

Largely copy from bf4 gist

where-or's People

Contributors

eric-guo avatar robmathews avatar ybur-yug avatar zedtux avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

where-or's Issues

Any plans to include tests?

Hi, are there any plans to introduce tests in to this library? Would love to see that before dropping this into our project. Thanks!

Eager-loading unscoped association generates empty WHERE clause

class Post < ActiveRecord::Base
  has_many :comments
  default_scope -> { where(deleted_at: nil) }
end

class Comment < ActiveRecord::Base
  belongs_to :post, -> { unscope(where: :deleted_at) }
end

Eager-loading an unscoped association generates an empty WHERE clause in combination with the where-or gem:

irb(main):001:0> Comment.includes(:post)
  Comment Load (0.2ms)  SELECT "comments".* FROM "comments"
  Post Load (0.9ms)  SELECT "posts".* FROM "posts" WHERE () AND "posts"."id" IN (1)
ActiveRecord::StatementInvalid: SQLite3::SQLException: near ")": syntax error: SELECT "posts".* FROM "posts" WHERE () AND "posts"."id" IN (1)
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/sqlite3-1.3.11/lib/sqlite3/database.rb:91:in `initialize'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/sqlite3-1.3.11/lib/sqlite3/database.rb:91:in `new'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/sqlite3-1.3.11/lib/sqlite3/database.rb:91:in `prepare'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/sqlite3_adapter.rb:284:in `block in exec_query'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/abstract_adapter.rb:484:in `block in log'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/abstract_adapter.rb:478:in `log'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/sqlite3_adapter.rb:281:in `exec_query'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/abstract/database_statements.rb:356:in `select'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/abstract/database_statements.rb:32:in `select_all'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/connection_adapters/abstract/query_cache.rb:70:in `select_all'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/querying.rb:39:in `find_by_sql'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/relation.rb:639:in `exec_queries'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/relation.rb:515:in `load'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/relation.rb:243:in `to_a'
    from .rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activerecord-4.2.7.1/lib/active_record/relation/delegation.rb:46:in `to_ary'
... 27 levels...

Compared to stock ActiveRecord:

irb(main):001:0> Comment.includes(:post)
  Comment Load (1.2ms)  SELECT "comments".* FROM "comments"
  Post Load (0.1ms)  SELECT "posts".* FROM "posts" WHERE "posts"."id" IN (1)
=> #<ActiveRecord::Relation [#<Comment id: 1, post_id: 1, body: "Lorem ipsum", deleted_at: nil, created_at: "2016-09-29 08:45:52", updated_at: "2016-09-29 08:45:52">]>

Using Rails v4.2.7.1. Where-or v0.1.2 and master exhibit the same behavior.

Gem Load Error is: nil is not a symbol

I just installed where-or gem in a brand new Rails 4.2 application and when I try to run my specs I got the following error:

bundler: failed to load command: rspec (/bundle/bin/rspec)
Bundler::GemRequireError: There was an error while trying to load the gem 'where-or'.
Gem Load Error is: nil is not a symbol
Backtrace for gem load error is:
/bundle/gems/where-or-0.1.4/lib/where-or.rb:95:in `private'
/bundle/gems/where-or-0.1.4/lib/where-or.rb:95:in `<module:QueryMethods>'
/bundle/gems/where-or-0.1.4/lib/where-or.rb:28:in `block in <top (required)>'
/bundle/gems/activesupport-4.2.7.1/lib/active_support/lazy_load_hooks.rb:38:in `instance_eval'
/bundle/gems/activesupport-4.2.7.1/lib/active_support/lazy_load_hooks.rb:38:in `execute_hook'
/bundle/gems/activesupport-4.2.7.1/lib/active_support/lazy_load_hooks.rb:28:in `block in on_load'
/bundle/gems/activesupport-4.2.7.1/lib/active_support/lazy_load_hooks.rb:27:in `each'
/bundle/gems/activesupport-4.2.7.1/lib/active_support/lazy_load_hooks.rb:27:in `on_load'
/bundle/gems/where-or-0.1.4/lib/where-or.rb:16:in `<top (required)>'
/usr/local/bundle/gems/bundler-1.13.6/lib/bundler/runtime.rb:91:in `require'
/usr/local/bundle/gems/bundler-1.13.6/lib/bundler/runtime.rb:91:in `block (2 levels) in require'
/usr/local/bundle/gems/bundler-1.13.6/lib/bundler/runtime.rb:86:in `each'
/usr/local/bundle/gems/bundler-1.13.6/lib/bundler/runtime.rb:86:in `block in require'
/usr/local/bundle/gems/bundler-1.13.6/lib/bundler/runtime.rb:75:in `each'
/usr/local/bundle/gems/bundler-1.13.6/lib/bundler/runtime.rb:75:in `require'
/usr/local/bundle/gems/bundler-1.13.6/lib/bundler.rb:106:in `require'
...

Looking at lib/where-or.rb:95 it seems that something is wrong as there are 2 times private and the first time, there is method definition on the same line.

`Relation passed to #or must be structurally compatible` fix?

Rails: 4.2.7.1
Ruby: 2.2.5p319

I have the following line

return query.where(scope_hash.inject(query) { |query, (scope_name, ids)| query.or(query.public_send(scope_name, ids)) })

Currently I am getting Relation passed to #or must be structurally compatible. In doing some research, I came across rails/rails#24055, wherein the proposed solution is rails/rails#24055 (comment). When comparing where-or.rb to the github link, it seems the change is implemented; however, I wanted to get a second opinion. Is there anything that can be done to the gem? Or does my issue lie within my own code?

chaining .or with .all clause

When chaining .or with .all I would expect the result to be .all.

With where-or gem:

> Post.where(id: 1).or(Post.all).to_sql
=> "SELECT \"posts\".* FROM \"posts\" WHERE \"posts\".\"id\" = 1  ORDER BY name ASC"

In Rails 5:

> Post.where(id: 1).or(Post.all).to_sql
=> "SELECT \"posts\".* FROM \"posts\""

Incompatible structure on seemingly compatible relations

I was pretty eager to utilize this gem, but have run into a snag.

# User.rb
class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :confirmable

  has_many :wikis
# has_many :wikis, through: :collaborators
  has_many :collaborators
  has_many :collaborated_wikis, through: :collaborators, source: :wiki

  after_initialize :init

  def init
    self.role ||= 'standard'
  end

  def admin?
    role == 'admin'
  end

  def premium?
    role == 'premium'
  end

  def standard?
    role == 'standard'
  end

  def publicize_wikis
    self.wikis.each { |wiki|
      wiki.update_attributes(private: false)
      wiki.collaborators.delete_all
    }
  end

end
# Wiki.rb
class Wiki < ActiveRecord::Base
  belongs_to :user

  has_many :collaborators
  has_many :users, through: :collaborators

  has_paper_trail :only => [:title, :body]
  has_permalink

  after_initialize :init

  def init
    self.private = false if self.private.nil?
  end

  def candidates
    User.where.not(id: self.users).where.not(id: self.user).where.not(role: 'admin')
  end

  scope :public_wikis, -> { where(private: false) }
end
# Collaborator.rb
class Collaborator < ActiveRecord::Base
  belongs_to :user
  belongs_to :wiki
end
# wiki_policy.rb
class WikiPolicy < ApplicationPolicy

  def index?
    true
  end

  def show?
    super && ( (!record.private) || (record.user == user || user.in?(record.users)) || (user.present? && user.admin?) )
  end

  def edit?
    show?
  end

  def destroy?
    user.present? && (record.user == user || user.admin?)
  end

  def private?
    user.present? && ((user.premium? && (record.user == user || record.new_record?)) || user.admin?)
  end

  class Scope
    attr_reader :user, :scope

    def initialize(user, scope)
      @user  = user
      @scope = scope
    end

    def resolve
      wikis = []
      if user.present? && user.admin?
        wikis = scope.all
      elsif user.present? && user.premium?
        # Here lies the issue - Incompatible relations
        wikis = scope.public_wikis.or(user.wikis).or(user.collaborated_wikis)
      else
        wikis = scope.public_wikis
      end
      wikis
    end
  end

end

So User has_many wikis that they own, and has_many collaborated wikis through collaborator. Wiki's has many users through collaborator. When I try:

wikis = scope.public_wikis.or(user.wikis).or(user.collaborated_wikis)

I get an error from user.collaborated_wikis, which should return the relation of wikis related to this user. user.wikis works the same, by providing the wikis owned by user through collaborators. If I take out the collaborated_wikis call, even though scope.public_wikis and user.wikis are of different classes (ActiveRecord_Relation vs ActiveRecord_Associations_CollectionProxy, respectively) they play well together. If you look at the class of user.collaborated_wikis, it is that of ActiveRecord_Associations_CollectionProxy. Going into the rails console, I can see that the result of user.collaborated_wikis is a list of all the wikis that the user collaborates on, so I know the HMT relation works, I just can't figure out why the gem is saying that the structures are incompatible. Any ideas?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.