Commit Graph

227 Commits

Author SHA1 Message Date
Carlos Antonio da Silva
a662a7894b Fix implicit join references option reversion in test 2013-03-15 14:17:59 -03:00
Yves Senn
34402c7623 make it possible to disable implicit join references.
Closes #9712.
2013-03-15 16:07:05 +01:00
Yves Senn
cd87c85ef0 Deprecate the :distinct option for Relation#count.
We moved more and more away from passing options to finder / calculation
methods. The `:distinct` option in `#count` was one of the remaining places.
Since we can now combine `Relation#distinct` with `Relation#count` the option
is no longer necessary and can be deprecated.
2013-03-15 14:15:47 +01:00
Yves Senn
a1bb6c8b06 rename Relation#uniq to Relation#distinct. #uniq still works.
The similarity of `Relation#uniq` to `Array#uniq` is confusing. Since our
Relation API is close to SQL terms I renamed `#uniq` to `#distinct`.

There is no deprecation. `#uniq` and `#uniq!` are aliases and will continue
to work. I also updated the documentation to promote the use of `#distinct`.
2013-03-15 14:15:47 +01:00
Cédric FABIANSKI
9f549212c3 Unprepared Visitor + unprepared_statement 2013-03-08 09:14:31 +01:00
wangjohn
d49f862b9a Added comments about the check_empty_arguments method which is called
for query methods in a where_clause. Also, modified the CHANGELOG entry
because it had false information and added tests.
2013-02-20 10:53:25 -05:00
Guillermo Iguaran
fa987cb8ec Reverting 16f6f25 (Change behaviour with empty array in where clause) 2013-02-08 14:22:10 -05:00
robertomiranda
16f6f2592e Change behaviour with empty array in where clause 2013-02-08 06:37:30 -05:00
Jon Leighton
c8d889905d Prevent Relation#merge from collapsing wheres on the RHS
This caused a bug with the new associations implementation, because now
association conditions are represented as Arel nodes internally right up
to when the whole thing gets turned to SQL.

In Rails 3.2, association conditions get turned to raw SQL early on,
which prevents Relation#merge from interfering.

The current implementation was buggy when a default_scope existed on the
target model, since we would basically end up doing:

  default_scope.merge(association_scope)

If default_scope contained a where(foo: 'a') and association_scope
contained a where(foo: 'b').where(foo: 'c') then the merger would see
that the same column is representated on both sides of the merge and
collapse the wheres to all but the last: where(foo: 'c')

Now, the RHS of the merge is left alone.

Fixes #8990
2013-01-27 20:34:52 +00:00
Chris Geihsler
7f6872e85b Added test case to prevent regression of chained, preloaded scopes. (#7490) 2013-01-19 18:53:25 -05:00
Yves Senn
947e1d5e85 deprecate assert_blank and assert_present.
They don't add any benefits over `assert object.blank?`
and `assert object.present?`
2013-01-05 18:04:52 +01:00
Rafael Mendonça França
14f1867661 Revert "[#8743] Test case"
This reverts commit 162e2859813b31c50700b453aa61992dfa57139e.

This commit was added by mistake, sorry 🙇
2013-01-05 05:11:39 -03:00
Cédric FABIANSKI
162e285981 [#8743] Test case
- Reverting #a3cf03ef99 fixes the issue

Conflicts:
	activerecord/test/cases/relations_test.rb
2013-01-05 04:39:32 -03:00
Jon Leighton
64c53d7ce4 Use separate Relation subclasses for each AR class
At present, ActiveRecord::Delegation compiles delegation methods on a
global basis. The compiled methods apply to all subsequent Relation
instances. This creates several problems:

1) After Post.all.recent has been called, User.all.respond_to?(:recent)
   will be true, even if User.all.recent will actually raise an error due
   to no User.recent method existing. (See #8080.)

2) Depending on the AR class, the delegation should do different things.
   For example, if a Post.zip method exists, then Post.all.zip should call
   it. But this will then result in User.zip being called by a subsequent
   User.all.zip, even if User.zip does not exist, when in fact
   User.all.zip should call User.all.to_a.zip. (There are various
   variants of this problem.)

We are creating these compiled delegations in order to avoid method
missing and to avoid repeating logic on each invocation.

One way of handling these issues is to add additional checks in various
places to ensure we're doing the "right thing". However, this makes the
compiled methods signficantly slower. In which case, there's almost no
point in avoiding method_missing at all. (See #8127 for a proposed
solution which takes this approach.)

This is an alternative approach which involves creating a subclass of
ActiveRecord::Relation for each AR class represented. So, with this
patch, Post.all.class != User.all.class. This means that the delegations
are compiled for and only apply to a single AR class. A compiled method
for Post.all will not be invoked from User.all.

This solves the above issues without incurring significant performance
penalties. It's designed to be relatively seamless, however the downside
is a bit of complexity and potentially confusion for a user who thinks
that Post.all and User.all should be instances of the same class.

Benchmark
---------

require 'active_record'
require 'benchmark/ips'

class Post < ActiveRecord::Base
  establish_connection adapter: 'sqlite3', database: ':memory:'
  connection.create_table :posts

  def self.omg
    :omg
  end
end

relation = Post.all

Benchmark.ips do |r|
  r.report('delegation')   { relation.omg }
  r.report('constructing') { Post.all }
end

Before
------

Calculating -------------------------------------
          delegation      4392 i/100ms
        constructing      4780 i/100ms
-------------------------------------------------
          delegation   144235.9 (±27.7%) i/s -     663192 in   5.038075s
        constructing   182015.5 (±21.2%) i/s -     850840 in   5.005364s

After
-----

Calculating -------------------------------------
          delegation      6677 i/100ms
        constructing      6260 i/100ms
-------------------------------------------------
          delegation   166828.2 (±34.2%) i/s -     754501 in   5.001430s
        constructing   116575.5 (±18.6%) i/s -     563400 in   5.036690s

Comments
--------

Bear in mind that the standard deviations in the above are huge, so we
can't compare the numbers too directly. However, we can conclude that
Relation construction has become a little slower (as we'd expect), but
not by a huge huge amount, and we can still construct a large number of
Relations quite quickly.
2012-11-30 14:06:48 +00:00
Carlos Antonio da Silva
a739340d3c Ensure ordering to make the test pass with postgresql 2012-11-18 16:27:50 -02:00
Dieter Komendera
22ed92dbae Add test to ensure preloading works as expected with "select" and "includes".
This didn't work in rails 3.1. See #2303 for more information and original pull request.
2012-11-18 13:17:11 +01:00
Juanjo Bazán
35ca953a27 loaded relations cannot be mutated by extending! 2012-10-28 22:17:34 +01:00
Jon Leighton
0096f53b25 nodoc the first_or_create methods and document alternatives 2012-10-19 15:56:18 +01:00
Jon Leighton
eb72e62c30 Add Relation#find_or_create_by and friends
This is similar to #first_or_create, but slightly different and a nicer
API. See the CHANGELOG/docs in the commit.

Fixes #7853
2012-10-19 13:18:47 +01:00
Tima Maslyuchenko
633ea6a826 learn ActiveRecord::QueryMethods#order work with hash arguments 2012-10-12 17:57:24 +03:00
Yves Senn
626f7df626 remove duplicated require statements in AR test cases 2012-10-09 21:33:54 +02:00
Isaac Sanders
7bf9db529e Model.select takes a variable list of arguments.
This is a cleaner version of #6916.

Closes #3165.
2012-08-23 13:51:10 -05:00
Ernie Miller
bf80522be4 Fix "last equality wins" logic in relation merge
This is a real fix (as compared to the band-aid in b127d86c), which uses
the recently-added equality methods for ARel nodes. It has the side
benefit of simplifying the merge code a bit.
2012-08-19 08:06:31 -04:00
Ernie Miller
b127d86c18 Fix merge error when Equality LHS is non-attribute
This is at best a band-aid for a more proper fix, since it won't truly
handle the removal of the previous equality condition of these other
nodes. I'm planning to put in some work on ARel toward supporting that
goal.

Related: rails/arel#130, ernie/squeel#153, ernie/squeel#156
2012-08-17 11:31:23 -04:00
Carlos Antonio da Silva
cf232e37ad Merge pull request #7133 from roshats/fix_update_all_with_blank_argument
Change Relation#update_all with blank argument to raise an ArgumentError 
instead of trying an update with empty fields.
2012-08-15 08:45:15 -07:00
Roman Shatsov
f28096476d raise ArgumentError if list of attributes to change is empty in update_all 2012-08-14 21:04:48 +03:00
Jon Leighton
55b24888bb Remove ActiveRecord::Base.to_a
On reflection, it seems like a bit of a weird method to have on
ActiveRecord::Base, and it shouldn't be needed most of the time anyway.
2012-08-03 11:51:52 +01:00
Jon Leighton
437851ea02 Add Relation#load
This method explicitly loads the records and then returns `self`.

Rather than deciding between "do I want an array or a relation?",
most people are actually asking themselves "do I want to eager load
or lazy load?" Therefore, this method provides a way to explicitly
eager-load without having to switch from a `Relation` to an array.

Example:

    @posts = Post.where(published: true).load
2012-08-01 21:59:46 +01:00
Bogdan Gusiev
92641efeec AR::Relation#order: make new order prepend old one
User.order("name asc").order("created_at desc")
    # SELECT * FROM users ORDER BY created_at desc, name asc

This also affects order defined in `default_scope` or any kind of associations.
2012-07-31 10:24:18 +03:00
Jon Leighton
b658cf1198 Deprecate ActiveRecord::Base.scoped.
It doesn't serve much purpose now that ActiveRecord::Base.all returns a
Relation.

The code is moved to active_record_deprecated_finders.
2012-07-27 17:27:47 +01:00
Jon Leighton
6a81ccd69d ActiveRecord::Base.all returns a Relation.
Previously it returned an Array.

If you want an array, call e.g. `Post.to_a` rather than `Post.all`. This
is more explicit.

In most cases this should not break existing code, since
Relations use method_missing to delegate unknown methods to #to_a
anyway.
2012-07-27 13:34:12 +01:00
Jon Leighton
4b4a85515b support relations created with a table alias 2012-07-13 11:44:45 +01:00
Jon Leighton
c433adffa2 Relation#inspect handles doesn't perform a new query on an already-loaded relation 2012-07-07 10:07:28 +01:00
Damien Mathieu
7d0053e6a7 Limit the number of records in Relation#inspect
While it's interesting to have the results array, it can make a console or a webpage freeze if there are a lot of them.
So this limits the number of records displayed in #inspect to 10 and tells how much were effectively found.
2012-07-06 20:04:38 +02:00
Jon Leighton
07314e64fd Show the records in Relation#inspect
The reason for removing the previous implementation of `#inspect` was
that it hid from you that you were dealing with a `Relation` rather than
an `Array`.

But it is still useful to be able to see the records, particularly if you're
writing something like the following in tests:

    assert_equal [foo], Post.where(:bar)

If the assertion fails, you want to see what records were actually
loaded.

So this implementation makes it clear that you've got a `Relation`, but
also shows your records.
2012-07-06 10:39:46 +01:00
Jon Leighton
70d3625760 disallow mutating a relation once loaded 2012-06-22 10:29:49 +01:00
Akira Matsuda
37a4dd5ccf a test case that ensures AR::Relation#merge can merge associations 2012-06-03 13:28:01 +09:00
Akira Matsuda
212a74d8b7 modulize AR::NullRelation
now we can invoke previously added scope extension methods
2012-06-01 14:46:13 +09:00
Ivan Kukobko
45d059b401 fixed typo in word finiding 2012-05-20 22:11:32 +03:00
Jon Leighton
62c6ac2f8d quarantine more deprecated stuff 2012-05-18 15:04:36 +01:00
Jon Leighton
ee16feae4a quarantine deprecated tests 2012-05-18 14:46:54 +01:00
Radoslav Stankov
64872d1e34 Relation#from to accept other Relation objects
Record.from("(#{sub_query.to_sql})")    -> Record.from(sub_query)
Record.from("(#{sub_query.to_sql}) a")  -> Record.from(sub_query, :a)
2012-05-17 02:36:13 +03:00
Andrew White
fa21b73ebb Return false for exists? with new records - fixes #6199. 2012-05-10 23:16:40 +01:00
Marcelo Silveira
56bf1f7455 Use take instead of first to avoid unwanted implicit ordering (fixes #6147) 2012-05-05 12:10:52 -03:00
Francesco Rodriguez
2f681254ee delete_all raise an error if a limit is provided - fixes #4979 2012-04-30 10:49:20 -05:00
Jon Leighton
0ed05b0e73 find and replace deprecated keys 2012-04-27 12:37:21 +01:00
Jon Leighton
df6f971e3a %s/find(:\(first\|last\|all\), \([^()]*\))/scoped(\2).\1/gcI amongst other things 2012-04-27 11:42:50 +01:00
Jon Leighton
b30996307d remove deprecate #all usage 2012-04-26 18:04:41 +01:00
Jon Leighton
e1a83690da remove deprecated scope stuff 2012-04-26 13:29:47 +01:00
Jon Leighton
40a711ce29 remove tests for #with_scope (it's now deprecated) 2012-04-25 17:52:28 +01:00