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