D For A Web Developer

Jacob Carlborg via Digitalmars-d digitalmars-d at puremagic.com
Thu May 1 03:44:41 PDT 2014


On 2014-04-30 22:38, Adam D. Ruppe wrote:

> Yeah, foreign keys are really an absolute must. So are uniqueness
> constraints. Rails can kinda do these, but in its own reinvented ways
> that don't actually hit the DB (at least not without add on gems)

Rails unique constraints do hit the DB, but they can be painfully slow. 
It's usually faster to let the DB handle it and handle the exception in 
Ruby.

> I also find myself really missing outer joins and views.

For outer joins:

1. You can always use raw SQL, also in combination with ActiveRecord

Post.joins(:comments).joins("outer join foos on foos.post_id = 
posts.id").where(title: "bar")

2. My preferred choice, using Squeel [1] (another gem). With Squeel the 
above would look like this:

Post.joins(:comments).joins{ foos.outer }.where(title: "bar")

It also supports queries like this:

Post.where{ |q| q.id >= 3 }

For views you can use raw SQL in the migration to create the view. Then 
it behaves just like a regular table. ActiveRecord won't know the 
difference.

At my previous work we used the SchemaPlus [3] gem. It supports foreign 
keys, views and indexes.

> That doesn't change the race condition because the database is still
> shared across those processes. With a regular SQL query, the database
> guarantees consistent, atomic operations in the DB engine itself, but
> with active record pattern, you give that up... while still having the
> shared data.

I'm not sure I understand. ActiveRecord does regular SQL queries. The 
example you wrote:

account = BankAccount.find(1)
account.balance -= 10
account.save!

Are you referring to if one process executes line 1 and another line 2?

> It also hides all the beauty of it :(
>
>> Properly escape values
>
> If you're escaping values, unless you're writing some low level database
> library, you're almost certainly doing it wrong.

I don't know how other libraries do it these days but last time I didn't 
use ActiveRecord it looked something like this:

query("select * from foo where name = ?", "foobar");

BTW, this is still how you need to do it in ActiveRecord when needing 
something more than the equal operator. It was quite similar in Rails 2 
as well. Rails 3 and later makes it a bit better. Very ugly. All values 
are far to the right and the query is to the left. It's get a quick 
overview of which values go where.

Therefore I prefer Squeel as soon I need to do something more advanced 
than the equal operator:

Foo.where{ |q| q.size >= 4 }

You can also use SQL functions:

Foo.where{ |q| q.created_at == q.getdate() }

> CSS is the view in that scenario. The HTML the object returns is just
> its fields wrapped up in tags and classes. Works really well, for my
> last big job, the designer worked almost exclusively in CSS and we got a
> lot of stuff done.

I never get that working. The HTML always need to change when the design 
changes.

> It calls functions on the variable. So like {$foo|capitalize} would be
> kinda like <%= capitalize(foo) %>. The plural example uses arguments to
> the function too so we can customize the words if it is plural or no.

Ah, I see.


> <html><% some ruby here %></html>
>
> I hate that stuff, especially when the view starts doing implicit
> database queries! Defeats the whole point of MVC separation if you ask me.

That's useful for looping and if-statements. I also sometimes but a 
variable there at the top. In Haml:

- @posts.each do |post|
   %h3= post.title
   .body= post.body

   - if current_url == post_url(post)
     = post.title

   - else
     = link_to post.title, post

This would of course be better handled with a partial and a view helper.

Yeah, I agree that it's ugly with database queries in the view. But it's 
very easy to end up with something like this, instead of the above:

- Post.all.each do |post|

Queries in the view can be good, it depends on how you look at it. If 
you write the query in the controller and then access the result in the 
view, the query will be executed in the view because since Rails 3 
queries are lazy. The advantage of this is the you can stream out the 
response [2].

> meh, with my libs, they might not be accessible to others, being poorly
> documented and all, but I know them and have used them for almost
> everything that's come up over the years. So for me, getting work done
> means spending an hour using D instead of days searching the web for
> some gem that won't even work right anyway.

For me it's the same with Rails. I know Rails and know a lot of useful gems.

[1] https://github.com/activerecord-hackery/squeel
[2] http://asciicasts.com/episodes/266-http-streaming
[3] https://github.com/lomba/schema_plus

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list