<div dir="ltr">I've found in cases where it's easier for me to be building the SQL myself Sequel (<a href="https://github.com/jeremyevans/sequel">https://github.com/jeremyevans/sequel</a>) is easier to wrestle than AR. The ability to build up SQL commands and pass them around like closures to be evaluated later or used as subqueries become particularly helpful.<br><br><div class="gmail_quote"><div dir="ltr">On Mon, Feb 29, 2016 at 9:02 PM Graham Ashton <<a href="mailto:graham@effectif.com">graham@effectif.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Sun, 28 Feb 2016, at 09:12 PM, gvim wrote:<br>
<br>
> I'm converting a Perl web application to Rails…<br>
<br>
>From the name of the function ("log_row_sql”) I’m wondering whether that query is run once to build a row of output in a multi-row table? If so, it’s an N+1 query waiting to be optimised…<br>
<br>
>       $sql .= q( FROM log_form l, activities a, packages p);<br>
>       $sql .= q(, vmaster m) unless $master eq 'e';<br>
>       $sql .= q( WHERE <a href="http://l.id" rel="noreferrer" target="_blank">l.id</a> = ?);<br>
>       $sql .= q( AND l.packageid = <a href="http://p.id" rel="noreferrer" target="_blank">p.id</a>);<br>
>       $sql .= q( AND l.activityid = <a href="http://a.id" rel="noreferrer" target="_blank">a.id</a>);<br>
>       $sql .= q( AND l.masterid = <a href="http://m.id" rel="noreferrer" target="_blank">m.id</a>) unless $master eq 'e';<br>
<br>
That looks like you’d need 4 ActiveRecord models – LogForm, Activity, Package and VMaster. A LogForm “belongs to" activity, package and vmaster (and they in turn probably "have many” – or possibly just one – activities).<br>
<br>
If my N+1 suspicion is right and you really need to pull back a set of results, you can improve on that nicely (from a performance point of view) by adjusting the `where()` part in this example so it identifies the right rows in the log_form table.<br>
<br>
  LogForm.where(id: the_id).includes(:activities, :packages, :vmaster)<br>
<br>
It’ll run 4 queries – one to find the matching log_form rows, and one more for each table in the `includes()` call.<br>
<br>
If you need to pull back more than a handful of results, this approach works really well.<br>
<br>
There’s also a find_by_sql method in ActiveRecord, and there’s absolutely nothing wrong with using it.<br>
<br>
> It seems this is not a good fit for Active Record and maybe Rails in<br>
> general?<br>
<br>
I might have missed something in the code you posted, but there’s nothing in the query leaping out at me.<br>
<br>
If my suggestion doesn’t look great, can you share the context that this function is called in? What does the app do with the results?<br>
<br>
--<br>
Graham Ashton (Founder, Agile Planner)<br>
<a href="https://www.agileplannerapp.com" rel="noreferrer" target="_blank">https://www.agileplannerapp.com</a> | @grahamashton | @agileplanner<br>
_______________________________________________<br>
Chat mailing list<br>
<a href="mailto:Chat@lists.lrug.org" target="_blank">Chat@lists.lrug.org</a><br>
Archives: <a href="http://lists.lrug.org/pipermail/chat-lrug.org" rel="noreferrer" target="_blank">http://lists.lrug.org/pipermail/chat-lrug.org</a><br>
Manage your subscription: <a href="http://lists.lrug.org/options.cgi/chat-lrug.org" rel="noreferrer" target="_blank">http://lists.lrug.org/options.cgi/chat-lrug.org</a><br>
List info: <a href="http://lists.lrug.org/listinfo.cgi/chat-lrug.org" rel="noreferrer" target="_blank">http://lists.lrug.org/listinfo.cgi/chat-lrug.org</a><br>
</blockquote></div></div>