Forum: Ruby on Rails Suggestion for Rails 4

7711f9afa01c45042b18a8ce31602590?d=identicon&s=25 Abram (Guest)
on 2012-11-03 22:44
(Received via mailing list)
When I began learning rails I found it frustrating that array and active
record relation objects could not be queried in the same fashion as
database tables. Before too much confusion let me explain.


When I want something from a database table I simply write something
like:
Product.where(:color=>'black') NOW, if I put a .to_sql after that
statement
I see something like "SELECT \"styles\".* FROM \"styles\" WHERE
\"styles\".\"color\" = 'black'"


So clearly, rails is magically converting that friendly statement into
something more meaningful to the backend. That's fantastic and makes my
life wonderful.


So here's my problem.. after running the query I am returned an active
record relation, which let's say is called @products. Now, let's say I
want
to further break that list of products into products that are big and
small. This would require one of two things.. either I must hit the
database twice being more selective, or I must iterate over @products
using
a block and such ruby magic as collect/map/select/etc...


To me neither of the above is a great option, and I must admit while
learning ruby on rails this was one of the biggest stumbling blocks for
me,
and one that has produced a massive amount of stackoverflow headaches
for
many others.


My suggestion to rails developers is to make rails more accessible to
beginners by allowing programmers to apply the same simplicity of
writing
an active record query to querying an active record relation object or
array of model objects.


For example, I want to now take @products and say:


@products.where(:size=>"small") and have this converted automagically by
rails to the appropriate statement @products.select{|product|
product.size
== 'small'}


I suppose this could work if rails were to query the object type first
before performing the query. Is the object type an array or active
record
relation, and is it in the expected format (collection of appropriate
objects)? If it is, then treat it as a virtual table and instead of
performing an sql query, hit it with a select block, etc.


I know understanding the underlying ruby code is good, and at times
would
be preferable to using active record style commands.. but for new users
getting off the ground, I think having both options would be beneficial.
Also, I feel it would be more consistency to the framework generally.


I have also posted this at reddit
http://www.reddit.com/r/rails/comments/12kyho/sugg...
5f94b9b346c2aa648a80bc259978e5bc?d=identicon&s=25 Colin Law (Guest)
on 2012-11-03 22:56
(Received via mailing list)
On 3 November 2012 21:43, Abram <funkdified@gmail.com> wrote:
>
> such ruby magic as collect/map/select/etc...
> active record query to querying an active record relation object or array of
> model objects.
>
>
> For example, I want to now take @products and say:
>
>
> @products.where(:size=>"small")

That should work, does it not for you?

Colin

 and have this converted automagically by
7711f9afa01c45042b18a8ce31602590?d=identicon&s=25 Abram (Guest)
on 2012-11-03 23:01
(Received via mailing list)
Well, it does, but it hits the DB again.
7711f9afa01c45042b18a8ce31602590?d=identicon&s=25 Abram (Guest)
on 2012-11-03 23:03
(Received via mailing list)
Basically it just chains on to the previous db query, but still runs a
new
one.. it doesn't query the active record relation object. Also, you
cannot
query an array of objects.. say @products = Product.all ... then say
@products.where(:color=>"black") .. You will get NoMethodError:
undefined
method `where' for #<Array:0x00000003918108>
19fad8b2f5f9948322c3fe0441265298?d=identicon&s=25 Jim ruther Nill (jimboker)
on 2012-11-04 05:15
(Received via mailing list)
On Sun, Nov 4, 2012 at 6:02 AM, Abram <funkdified@gmail.com> wrote:

> Basically it just chains on to the previous db query, but still runs a new
> one.. it doesn't query the active record relation object. Also, you cannot
> query an array of objects.. say @products = Product.all ... then say
> @products.where(:color=>"black") .. You will get NoMethodError: undefined
> method `where' for #<Array:0x00000003918108>


If you're running the code in the console, it hits the db immediately.
But
if it's in the actual application, it won't hit the db until you need to
access the records
which usually happens when you call each or map or collect on the active
relation object.  So given your code, if you want to get all black and
small objects, you can

@products = Product.where(color: 'black')
@products = @products.where(size: 'small')

these two lines will not actually create the product records and will
not
yet hit the db until you want to iterate each of the products.

As for calling Product.all, I checked the api and it doesn't explicitly
say
that #all returns an array.  But if you know that beforehand, you
shouldn't
have any issues
with chaining methods.


>>> database tables. Before too much confusion let me explain.
>>> life wonderful.
>>> To me neither of the above is a great option, and I must admit while
>>>
>>> relation, and is it in the expected format (collection of appropriate
>>>
> To view this discussion on the web visit
> https://groups.google.com/d/msg/rubyonrails-talk/-....
>
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>



--
7711f9afa01c45042b18a8ce31602590?d=identicon&s=25 Abram (Guest)
on 2012-11-04 09:40
(Received via mailing list)
Jim, Thanks for that.

What I mean is I want small and large black products attached to two
separate variables, say @blacksmall and @blacklarge.. both separated out
from @products which initially resulted from the Product.where(:color =>
'black) query. I know it's a stupid example, but I'm just wanting that
functionality, and think it would be an improvement in rails to enable
using active record queries on objects that are arrays of objects as
they
are represented in the table. If rails treats table rows as model
objects
why not treat a collection of model objects in the same way, allowing
the
same dsl for access/limiting what's within the collection.

Thanks
6dbddfda34303f8d83620f7293612671?d=identicon&s=25 Tommaso Visconti (Guest)
on 2012-11-04 11:21
(Received via mailing list)
Abram ha scritto:
> allowing the same dsl for access/limiting what's within the collection.
I'm not an expert of performances, but maybe databases like postgres or
mysql are faster than other solutions to retrieve data from a complex
query, so the solution to run a new query is better than filtering a
ruby collection, which can be simple but can already be very very
complex (think to db like openstreetmaps and you want to calculate a
path...)
5f94b9b346c2aa648a80bc259978e5bc?d=identicon&s=25 Colin Law (Guest)
on 2012-11-04 11:33
(Received via mailing list)
On 4 November 2012 08:38, Abram <funkdified@gmail.com> wrote:
> dsl for access/limiting what's within the collection.
Once you convert to an array then you have lost the knowledge about
the database.  Just keep everthing as activerecord collections and all
will be well. Rails will defer running queries until it has to as far
as it can in order to keep everything reasonably efficient.

So
@products = Product.where :color => 'black'
@smallproducts = @products.where :size => 'small'
@largeproducts = @products.where :size => 'large'

What is the problem?

Colin
6883e5ef03484d4fcef507d7b4f1d243?d=identicon&s=25 Matt Jones (Guest)
on 2012-11-05 00:55
(Received via mailing list)
On Sunday, 4 November 2012 03:38:56 UTC-5, Abram wrote:
> why not treat a collection of model objects in the same way, allowing the
> same dsl for access/limiting what's within the collection.


An interesting idea, but by the time you've written enough code to
support
things like joins you've basically recreated an RDBMS inside of
ActiveRecord. The alternative would be to support only a subset, but
that
seems *worse* than no support at all...

--Matt Jones
7711f9afa01c45042b18a8ce31602590?d=identicon&s=25 Abram (Guest)
on 2012-11-05 09:39
(Received via mailing list)
Matt,

I appreciate your answer... a good explanation :)

I'll drop it now

Abram
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.