find conditions question

Quick question , in a find statement, particularly the :conditions part.
if you see something like conditions => ["user = ?", user])
what would you be drawing the first "user" from and the second ? I'm
taking this from the AWDWR book.
If user is a column / method in the model , are you just repeat it
twice , or would you say
user = ?, tom ? I'm confused.

TIA
Stuart

The user in the quoted string is part of the final SQL statement; the other

user is accessing a variable. The array method being used here provides

reasonable security against SQL injection attacks - if you said

“user = #{user}”, malicious users could potentially insert arbitrary code.

The [] method automatically escapes SQL metacharacters, so it’s safe.

Hope this helps!

Let me make sure I got this right -
if the column name was user and then I did
user = "jack"
:conditions => ["user ?" <- this is the column, user <- this is jack] ?

Stuart

Dark Ambient wrote:

Let me make sure I got this right -
if the column name was user and then I did
user = "jack"
:conditions => ["user ?" <- this is the column, user <- this is jack] ?

Stuart
  
Yes. Be sure to check your development log, since it will show the
full SQL query that was actually run and can give great insight into how
what you're passing in your find translates into the final query. I
recommend running a tail -f on the log in one window and experimenting
with different commands in script/console in another window side-by-side
for this purpose. Very educational.

Thank you Jon, excellent recommendation - didnt know about that fact.
Stuart

Actually , I'm totally confused about what I'm seeing in the log . It
looks like there are multiple queries going on. The one that stands
out is the 2nd one , but I'm putting the find on the cdetails table
not the users.

user = 11
@cdetails = Cdetail.find(:all, :conditions => ["user_id = ?", user])

Parameters: {"action"=>"index", "controller"=>"cdetails"}
[4;36;1mUser Columns (0.000000)e[0m e[0;1mSHOW FIELDS FROM userse[0m
[4;35;1mUser Load (0.000000)e[0m e[0mSELECT * FROM users WHERE
(users.`id` = 11 ) LIMIT 1e[0m
[4;36;1mCdetail Columns (0.000000)e[0m e[0;1mSHOW FIELDS FROM cdetailse[0m
  e[4;35;1mSQL (0.000000)e[0m e[0mSELECT count(*) AS count_all FROM
cdetails e[0m
  e[4;36;1mCdetail Load (0.000000)e[0m e[0;1mSELECT * FROM cdetails
ORDER BY id LIMIT 0, 5e[0m

The

Parameters: {"action"=>"index", "controller"=>"cdetails"}

part suggests to me you did something from the browser window, not the
console. When you load a page in your rails app in a browser rails is
going to make LOTS of SQL queries. Your syntax looks correct though.
Assuming that all the model relationships and tables are setup
correctly, from this...

@cdetails = Cdetail.find(:all, :conditions => ["user_id = ?", user])

I would expect to see something like...

SELECT * FROM cdetails WHERE user_id = 11

In the log, which I assume is what you're going for.

Dark Ambient wrote:

user = 11
@cdetails = Cdetail.find(:all, :conditions => [“user_id = ?”, user])

If you just did that from the console, Rails would run just the one query on the Cdetails table. If you’re running it from the browser, there is probably some code referencing the user object(not just code that says user = 1) in there that you’re missing.

Yep, works correctly in console. I guess something maybe is
interferring in the console.

Stuart