Rails 3 Beginner to Builder 2011 Week 7

  • 6,062 views
Uploaded on

This is the 7th of 8 presentations given at University of Texas during my Beginner to Builder Rails 3 Class. For more info and the whole series including video presentations at my …

This is the 7th of 8 presentations given at University of Texas during my Beginner to Builder Rails 3 Class. For more info and the whole series including video presentations at my blog:


http://schneems.com/tagged/Rails-3-beginner-to-builder-2011

More in: Education , Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
6,062
On Slideshare
0
From Embeds
0
Number of Embeds
9

Actions

Shares
Downloads
104
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Beginner to Builder Week 7July, 2011Sunday, July 31, 11
  • 2. Rails - Week 7 • SQL Crash Course • where & find • method_missing • scopes and class methods • Pagination • full text search • Rake vs. Script/Runner@SchneemsSunday, July 31, 11
  • 3. SQL • Structured Query Language • Used to manage data in RDBMS (relational database management system) • Active Record hides our SQL User.where(:username => "foo").to_sql => SELECT "users".* FROM "users" WHERE "users"."username" = foo@SchneemsSunday, July 31, 11
  • 4. Find • find by uniqe id, or ids • find_by_#{:column_name} User.find(1) User.find(1,2,3) User.find_by_username(schneems)@SchneemsSunday, July 31, 11
  • 5. Method Missing User.foo_foo NoMethodError: undefined method `foo_foo for #<Class: 0x105187be8>@SchneemsSunday, July 31, 11
  • 6. Method Missing class User def self.method_missing(method_name, *args, &block) puts "You just called #{method_name}" end end User.foo_foo >> "You just called foo_foo"@SchneemsSunday, July 31, 11
  • 7. Method Missing class User < ActiveRecord::Base def self.method_missing(method_name, *args, &blk) if method_name.to_s =~ /^foo_foo_find_by_.*/ column = method_name.to_s.gsub("foo_foo_find_by_", "") User.where(column.to_sym => args.first) else super end end end User.foo_foo_find_by_username("schneems")@SchneemsSunday, July 31, 11
  • 8. Active Record • Active Record’s Query API find where (:conditions) includes (:include) group order limit offset joins having http://m.onkey.org/active-record-query-interface@SchneemsSunday, July 31, 11
  • 9. Order & Offset # Order# defaults to ascending User.order(:created_at).first #<User id: 1, ... User.order(created_at DESC).first #<User id: 55, ... # Offset User.order(:created_at).offset(1).first #<User id: 2, ... User.order(:created_at).offset(2).first #<User id: 3, ...@SchneemsSunday, July 31, 11
  • 10. Limit & Count # Limit User.limit(3).all [ #<User ... >, #<User ... >, #<User ... > ] # Count User.count => 55@SchneemsSunday, July 31, 11
  • 11. Group • Group # Group User.group(:hometown).count(:hometown) #<OrderedHash { "Austin, Texas"=>28, "Alexandria, MN"=>1, "Warsaw, Poland"=>1, # ... }@SchneemsSunday, July 31, 11
  • 12. Joins # Joins BlogPost.joins(:user).where(:user_id => 2).first => #<BlogPost id: 13023, name: The best of times>@SchneemsSunday, July 31, 11
  • 13. Include # Include pre-fetches data User.where(:id => 3).includes(:posts => :comments) user = User.find(3) post = user.posts.all.first post.comments@SchneemsSunday, July 31, 11
  • 14. Having # having User.group(:hometown).having("COUNT(hometown) > 22").count #<OrderedHash {"Austin, Texas"=>28, "Austin, TX"=>102, "San Francisco, CA"=>92, "Dallas, TX"=>56}>@SchneemsSunday, July 31, 11
  • 15. Where • can take raw sql statement User.where("username = foo").to_sql => "SELECT "users".* FROM "users" WHERE (username = foo)"@SchneemsSunday, July 31, 11
  • 16. Where • Like # Like does a search using % as wildcard User.where("username like %foo%") # will match ...zfoo, fooz..., etc.@SchneemsSunday, July 31, 11
  • 17. Where • Null # NULL checks blank entries User.where("username IS NULL") # NOT negates query User.where("username IS NOT NULL")@SchneemsSunday, July 31, 11
  • 18. Where • Equality Operators # <> is SQL not equal User.where("username <> foo") # "greater than" User.where("popularity > 5") # "less than" User.where("popularity < 5")@SchneemsSunday, July 31, 11
  • 19. Where • SQL Functions # DATE() is a SQL function User.where("DATE(created_at) > DATE(#{5.days.ago})") # Other Functions: # AVG, SUM, COUNT, MIN, MAX@SchneemsSunday, July 31, 11
  • 20. Where • (?) passes data into SQL safely User.where("DATE(created_at) > DATE(?)", 5.days.ago)@SchneemsSunday, July 31, 11
  • 21. SQL Security • SQL injection attacks name = " or 1 DROP TABLE USERS" # Bad User.where("name = #{name}") # Good User.where("name = ?", name) User.where(:name => name)@SchneemsSunday, July 31, 11
  • 22. ActiveRecord • Lazy Loading # stores Query, doesn’t hit the DB cars = Car.where(:colour => black) # .each Fires "select * from cars where ..." cars.each {|c| puts c.name } # Now We can Chain Item.limit(10).order(created_at DESC)@SchneemsSunday, July 31, 11
  • 23. Scopes • Re-use your queries class Product < ActiveRecord::Base scope :discontinued, where(:discontinued => true) scope :cheap, where("price < 5") end Product.discontinued.first Product.discontinued.cheap.first@SchneemsSunday, July 31, 11
  • 24. Scopes • Re-use your queries class Product < ActiveRecord::Base scope :cheaper_than, lambda { |price| where("price < ?", price) } end Product.cheaper_than(5).first@SchneemsSunday, July 31, 11
  • 25. Class Methods • Re-use your queries • Better than scopes class Product < ActiveRecord::Base def self.cheaper_than(price) where("price < ?", price) end end Product.cheaper_than(5).first Product.cheaper_than(5).order.limit(5).first@SchneemsSunday, July 31, 11
  • 26. Rake # /lib/tasks/users.rake namespace :users do desc "Create dummy users" task :populate => :environment do 5.times do User.build(:name => Faker.first_name) end end end # execute with > rake users:populate@SchneemsSunday, July 31, 11
  • 27. Rake • Can be used independently from Rails # /lib/tasks/foo.rake namespace :foo do desc "foo bars" task :bar do # ... end end@SchneemsSunday, July 31, 11
  • 28. Script/Runner # /lib/user_populate.rb 5.times do User.build(:name => Faker.first_name) end # execute with > script/runner /lib/user_populate.rb@SchneemsSunday, July 31, 11
  • 29. Rake Wins • Versatile • Useful outside of rails • favored over script/runner@SchneemsSunday, July 31, 11
  • 30. Pagination • Split up large data into chunks • will_paginate gem post = BlogPost.paginate :page => params[:page], :per_page => 20 post.total_count # => 200 post.count # => 20@SchneemsSunday, July 31, 11
  • 31. Full Text Search # SQL Like BlogPost.where("title like %?%", params[:title]) # slow # doesnt deal with # punctuation # pluralization # etc.@SchneemsSunday, July 31, 11
  • 32. SOLR • Open Source Search Server • Based on Lucene • Fast • Feature rich • Easily Accessed ruby API wrappers@SchneemsSunday, July 31, 11
  • 33. Sunspot GEM class BlogPost < ActiveRecord::Base searchable do text :title, :body text :comments do comments.map { |comment| comment.body } end time :published_at string :sort_title do title.downcase.gsub(/^(an?|the)/, ) end end end@SchneemsSunday, July 31, 11
  • 34. Sunspot GEM • Paginated BlogPost.search do fulltext best pizza with(:published_at).less_than Time.now order_by :published_at, :desc paginate :page => 2, :per_page => 15 facet :category_ids, :author_id end@SchneemsSunday, July 31, 11
  • 35. Sphinx • Open Source • Full text search server@SchneemsSunday, July 31, 11
  • 36. Thinking Sphinx GEM class Article < ActiveRecord::Base define_index do # fields indexes subject, :sortable => true indexes content indexes author.name, :as => :author, :sortable => true # attributes has author_id, created_at, updated_at end end@SchneemsSunday, July 31, 11
  • 37. Thinking Sphinx GEM Article.search "topical issue" Article.search "something", :order => :created_at, :sort_mode => :desc@SchneemsSunday, July 31, 11
  • 38. Sphinx • Flying Sphinx add-on in heroku@SchneemsSunday, July 31, 11
  • 39. 3rd Parties/Black Box • Index Tank # Connect to Service api = IndexTank::Client.new "<YOUR API URL HERE>" index = api.indexes "<YOUR INDEX NAME>" # add documents docid = "<YOUR DOCUMENT ID>" text = "<THE TEXTUAL CONTENT>" index.document(docid).add({ :text => text }) # search documents results = index.search "foo"@SchneemsSunday, July 31, 11
  • 40. Questions? http://guides.rubyonrails.org http://stackoverflow.com http://peepcode.com@SchneemsSunday, July 31, 11