Skip to content

Instantly share code, notes, and snippets.

@azinazadi
Created November 16, 2011 12:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save azinazadi/1369968 to your computer and use it in GitHub Desktop.
Save azinazadi/1369968 to your computer and use it in GitHub Desktop.
'
rails 1.9 new hash syntax
new_hash = {simon: "Talek", lorem: "Ipsum"}
###Rspec
%cucumber
save_and_open_page
###MIGRATION
Methods:
create_table(name, options)
drop_table(name)
rename_table(old_name, new_name)
add_column(table_name, column_name, type, options)
rename_column(table_name, column_name, new_column_name)
change_column(table_name, column_name, type, options)
remove_column(table_name, column_name)
add_index(table_name, column_name, index_type)
remove_index(table_name, column_name)
change_table(table_name) {|Table.new(table_name, self)| ...}
change_column_default(table_name, column_name, default)
change_column_null(table_name, column_name, null, default = nil)
Available Column Types (mappings are below):
* integer
* float
* datetime
* date
* timestamp
* time
* text
* string
* binary
* boolean
* decimal :precision, :scale
Valid Column Options:
* limit
* null (i.e. ":null => false" implies NOT NULL)
* default (to specify default values)
* :decimal, :precision => 8, :scale => 3
Rake Tasks:
rake db:schema:dump: run after you create a model to capture the schema.rb
rake db:schema:import: import the schema file into the current database (on
error, check if your schema.rb has ":force => true" on the create table
statements
./script/generate migration MigrationName: generate a new migration with a new
'highest' version (run './script/generate migration' for this info at your
fingertips)
rake db:migrate: migrate your current database to the most recent version
rake db:migrate VERSION=5: migrate your current database to a specific version
(in this case, version 5)
rake db:rollback: migrate down one migration
rake db:rollback STEP=3: migrate down three migrations
rake db:migrate RAILS_ENV=production: migrate your production database
rake db:create RAILS_ENV='test' #create the test database
SQL:
Queries can be executed directly:
execute 'ALTER TABLE researchers ADD CONSTRAINT fk_researchers_departments
FOREIGN KEY ( department_id ) REFERENCES departments( id )'
Example Migration:
class UpdateUsersAndCreateProducts < ActiveRecord::Migration
def self.up
rename_column "users", "password", "hashed_password"
remove_column "users", "email"
User.reset_column_information
User.find(:all).each{|u| #do something with u}
create_table "products", :force => true do |t|
t.column "name", :text
t.column "description", :text
t.column "price", :decimal, :precision => 9, :scale => 2
t.column "category_id", :integer
end
#the rails 2.0 way:
create_table :people do |t|
t.integer :account_id
t.string :first_name, :last_name, :null => false
t.text :description
t.references :category # is the equivalent of t.integer :category_id
t.timestamps
end
end
def self.down
rename_column "users", "hashed_password", "password"
add_column "users", "email", :string
drop_table "products"
end
end
Find Highest version:
script/runner "puts ActiveRecord::Migrator.current_version"
Database Mapping
Rails db2 mysql openbase Oracle
:binary blob(32678) blob object blob
:boolean decimal(1) tinyint(1) boolean number(10)
:date date date date date
:datetime timestamp datetime datetime date
:decimal decimal decimal decimal decimal
:float float float float number
:integer int int(11) integer number(38)
:string varchar(255) varchar(255) char(4096) varchar2(255)
:text clob(32768) text text clob
:time time time time date
:timestamp timestamp datetime timestamp date
Rails postgresql sqlite sqlserver Sybase
:binary bytea blob image image
:boolean boolean boolean bit bit
:date date date datetime datetime
:datetime timestamp datetime datetime datetime
:decimal decimal decimal decimal decimal
:float float float float(8) float(8)
:integer integer integer int int
:string * varchar(255) varchar(255) varchar(255)
:text text text text text
:time time datetime datetime time
:timestamp timestamp datetime datetime timestamp
Version 7, updated 140 days ago.
'
chp 12
5:50
fri
11:34 - 12:30 work on exercises of ajax
try to put it in line items not on store controller .
tue
10:30 - 12
10:15 - 11
turn
10:30 - 12
3 - 5
thursday
12:50 - 14
3 - 4:11 * localization
7 - 8:30
friday
11:50 - 12:20
2:20 - 3:20
17 - 18:10 Active Records
6:40 -
saturday
8 - 9
11:30 - 12
2 - 2:30
*** ITINERARY RECEIPT ***
AGENCY/AIRLINE NAME DATE OF ISSUE 19AUG11
AVIAREPS AG WALLDORF FRANKFURT RLOC W5 - Q7RTF
NAME: AZADIYAZDI/ATIN MRS
E-TICKET NUMBER: 5372100349460
DATE FLIGHT DEPARTURE AIRPORT ARRIVAL AIRPORT TIME CLASS BAG
21AUG W5 5059 DUS-DUSSELDORF, GERMAN IKA-IMAM KHOMEINI - TE 1145 V -OK 40K
02OCT W5 5060 IKA-IMAM KHOMEINI - TE DUS-DUSSELDORF, GERMAN 0620 T -OK 40K
RESTRICTIONS: NON-END/FARE CODE W5-413/MAX WEIGHT PER PIECE 23KG/ REF
50EUR NOSHOW 50EUR
FORM OF PAYMENT: MISC/CP/INVOICE//AZAD/108086
FARE: BASE IT EUR
TAX/FEE/CHARGE 3.75DE/25.00OY/56.85XT
TOTAL IT EUR
Notice: "Carriage and other services provided by the carrier are subject to
conditions of carriage, which are hereby incorporated by reference.
These conditions may be obtained from the issuing carrier."
#RAKE
rake --tasks
rake -T
rake routes
rake --describe task:name:and:options
rake db:create RAILS_ENV='test'
class Post < ActiveRecord::Base
validates_presence_of :title, :body
validates_uniqueness_of :title
end
Some people consider testing validations to be useless because I can be pretty sure that Rails has already done so. Considering validations are probably the lowest level of architecture in my models, it's a good idea just to verify that they're doing what I think they're doing.
describe Post do
before(:each) do
@post = Post.new(valid_post_hash) # grabs the hash below
end
it "should be valid" do
@post.should be_valid
end
it "should not be valid without a title" do
@post.title = ''
@post.should_not be_valid
end
it "should not be valid without a body" do
@post.body = ''
@post.should_not be_valid
end
def valid_post_hash
{:title => 'test', :body => 'test body'}
end
end
RSpec is not as readable as many would like it to be, but hopefully it's readable enough that I don't need to explain the above. I will mention some optional items that could be put in there:
before(:all) do
# this will be run once before all examples in this describe block
end
before do
# same as before(:each)
end
after(:each) do
# this will be run once after each example
@post.destroy unless @post.new_record?
end
after(:all) do
# this will be run once after all examples in this describe block
# Useful tasks to put in here are:
Post.destroy_all
end
Strings:
'foo'.should == 'foo'
'foo'.should === 'foo'
'foo'.should_not equal('foo')
''.should be_empty
'foo with bar'.should include('with')
'http://fr.ivolo.us'.should match(/http:\/\/.+/i)
nil.should be_nil
Numbers:
100.should < 200
200.should >= 100
(200 - 100).should == 100
# (100 - 80) is less than 21
100.should be_close(80,21)
Arrays:
[1,2,3].should have(3).items
[].should be_empty
[1,2,3].should include(2)
Hashes:
{}.should be_empty
{:post => {:title => 'test'}}.should have_key(:post)
{:post => {:title => 'test'}}.should_not have_key(:title)
false.should be_false
true.should be_true
Records:
# assuming @post = Post.new(:title => 'test')
@post.should be_instance_of(Post)
@post.should respond_to(:title)
MOCKING
describe PostsController, "comment", :behaviour_type => :controller, do
before do
@post = mock_model(Post)
Post.should_receive(:find).and_return(@post)
@comment = mock_model(Comment)
Comment.should_receive(:new).with.({:title => 'comment title', :body => 'comment body'}).and_return(@comment)
@blogger = mock_model(User)
@controller.instance_variable_set(:@blogger, @blogger)
end
it "should add comments to the post" do
@comment.should_receive(:save).and_return(true)
@post.comments.should_receive(:concat).and_return(@comment)
post :comment, :id => @post.id, :comment => {:title => 'comment title', :body => 'comment body'}
flash[:notice].should match(/success/i)
response.should redirect_to(posts_path(@blogger, @post))
end
end
L A M B D A
Ever done something ugly like this?
old_count = Article.count
@article.tags.create(...)
Article.count.should == old_count+1
Here''s a better way:
lambda { @article.tags.create(...) }.should change(Article, :count).by(1)
Other possibilities include:
lambda { @article.tags.create(...) }.should change(Article, :count).from(0).to(1)
lambda { @article.title = 'new title' }.should change(@article, :title).to('new title')
2. Ever done this in TestUnit?
assert_raises (ActiveRecord::RecordNotFound) do
Article.find(0)
end
Heres how you can do that in rspec:
lamda{ Article.find(0) }.should raise_error(ActiveRecord::RecordNotFound)
#GIT
to modify a commit
You can use git rebase, for example, if you want to modify commit bbc643cd, run
$ git rebase bbc643cd^ --interactive
In the default editor, modify 'pick' to 'edit' in the line whose commit you want to modify. Now you can use
$ git commit --amend
to modify the commit, and after that
$ git rebase --continue
to return back to the previous head commit.
#BASH
tails -f logfile
##Active Records
#CRUD
@order = Order.new(params[:order])
total = Product.find(product_list).sum(&:price)
cart = Cart.find_or_initialize_by_user_id(user.id)
cart.items << new_item
cart.save
also: Cart.find_or_create_by...
#SQL and ActiveRecord
pos = Order.where(["name = ? and pay_type = 'po'", name])
pos = Order.where("name = :name and pay_type = :pay_type", {:pay_type = pay_type, :name => name})
pos = Order.where(:name => params[name], :pay_type => params[:pay_type])
User.where("name like ?", params[:name]+"%")
%Order Limit Offset
orders = Order.where(:name => 'Dave').order("pay_type, shipped_at DESC").limit(10).offset(page_num*page_size)
%Select Join => the result will be readonly
LineItem.select('li.quantity').
where("pr.title = 'ruby programming'").
joins("as li inner join products as pr on li.product_id = pr.id")
%group
summary = LineItem.select("sku, sum(amount) as amount").group("sku")
%lock => we offen use transactions instead
%getting column statistics
average = Order.average(:amount)
" maximum
" minimum
" sum(:amount)
" count
result = Order.where("amount > 20").maximum(:price).group(:state) #=> [["TX",123],["NC",354]]
%scopes
class Order...
scope :last_n_days, lambda { |days| where('updated < ?', days) }
...
last_week = Order.last_n_days(7)
scope :checks, where(:pay_type => :check)
last_week_checks = Order.checks.last_n_days(7)
-> take care of using order and limit only once in total chain of scopes
#writin ur own sql
orders = Order.find_by_sql("select name, pay_type from orders")
%reload data
stock.reload
#update
order.save
order.update_attribute(:name, "Barney")
order.update_attributes(:name => "Barney", :email => "@")
order.update_attributes(params[:order])
%read and update using id as reference
order = Order.update(12, :name => "barney")
-> it can also be used to update multiple rows
result = Product.update_all("price = 1.1*price", "title like '%Java'")
-> updates all products price by 10% which have Java in their title
-> usually return the number of affected rows (DB dependent)
# save, save!, create, create!
##Action Dispatch and Action Controller
Action Pack = Action Dispatch + Action Controller + Action View
REST = Representational State Transfer
-> update -> put
** rake routes -> show
%Seven Methods and urls
index (products_url or path), new (new_product_url), create, show (product_url), edit (edit_product_url), update, destroy
%limiting routed actions
resources :comments, :except => [:update, :destroy]
%Adding Additonal Actions
resources :products do
get :who_bought, :on => :member #or :on => :collection
#Nested Resources
resources :products do
resources :reviews
end
-> the path to review must be prefixed with a product: /products/99/reviews/4
-> named_route: product_review
%Shallow Route Nesting
resources :products, :shallow => true do
resources: reviews
end
/products/1/reviews => product_reviews_index_path(1)
/reviews/2 => reviews_path(2)
%Formats
/store/show/1.xml
/store/show/1?format=xml
respond_to do |format|
format.yaml { render :text => @product.to_yaml }
end
#Testing Routes
...
##Processing of Requests
%Action Methods (How does a responsing method get found in a controller)
1- a public method with the same name as the incomming action
2- method_missing method of the controller
3- a template named after the current controller and action
4- UnknownAction error
%Controller Environment
* action_name
* cookies
* headers
* params
* request
* request_method => :delete, :get, :head, :post, :put
* method => the same as request_method except head...
* delete?, get?, head?, post?, put?
* xml_http_request? or xhr? => is it ajax? dependent of request
* url => the full URL
* protocol, host, port, path, query_string => protocol://host:port/path?query_string
* domain => the last two components of the domain name
* host_with_port => "host:port"
* port_string
* ssl?
* remote_ip => multiple ips if behind proxy
* path_without_extension, path_without_format_and_extension, format_and_extension
* env => like, request.env['HTTP_ACCEPT_LANGUAGE']
* accepts => accepts value of the mime type of request
* format => value of content-type of request
* mime_type
* content_type
* headers => complete set of http headers
* body :the request body as an I/O stream
* content_length: number of bytes purported to be in the body
* response
* session
* logger
* Renderin Templates
-> default template path: app/views/CONTROLLER/ACTION.TYPE.XXX where type is html, atom or js and XXX is erb or builder or rjs etc.
%Render method
* render(:text => "hello") #no template interpretation
* render(:inline => string, [:type => "erb, builder or rjs"], [:locals => hash]) #interpret string as a template
* render(:file => path, [:use_full_path => true|false]) #renders a file
* render(:template => "blog/short_list", ...)
* render(:partial => name, ...)
* render(:nothing => true) #sends an empty body to the client
* render(:xml => stuff) #sends stuff as text, forcing the content type to be application/xml
* render(:json=> stuff, [:callback => hash]) #like xml. call back is the name of a js function in client which then will feeded by the output json
* render(:update) do |page| #renders the block as an rjs tempalte
page[:cart].replace_html :partial => 'cart', :object => @cart
page[:cart].visual_effect :blind_down if @cart.total_items == 1
end
% there is always 3 optional parameters: :status, :layout, :content_type
. the layout says the result should be wrapped out in a layout, like the default application.html.erb
** render_to_string, returns a string, no DoubleRenderError :)
% Sendin Files and other data
* send_data(png_data, :type=>'image/png', :disposition => "inline | attachment") #sends a datastream
* send_file
%Redirects
* redirect_to(:action => ..., options)
* redirect_to(:path =>)
* redirect_to(:back)
* Sessions
-> they are easy loaded
1- session_store = :cookie_store => default , max 4kb
2- session_store = :p_store => stores each session in an individual file in PStore format
3- session_store = :active_record_store => stores the data in database, it just stores the row id in the users cookies
4- session_store = :drb_store => stores the data on a DRb server, for applications running on several servers
5- session_store = :mem_cache_store => distributed object caching system
6- session_store = :memory_store => stores every thing in local memory without serialisation. not a good idea
7- session_store = :file_store => store in flat files. just strings. pretty useless for rails apps
> for small sessions cookies are best solution. for larger ones active record and drb
%session Expiry and Cleanup
-> in serverside sessions they need to get cleaned up after user logs out or in a certain amount of deactivity time
-> the best way is to clean the data on server, and not to expire the cookie on client
* in active records sessions updated_at is usefull: delete from sessions where now() - updated_at > 3600;
%Flash: Communicating between actions
-> it is stored in session
* flash => will be passed to the next action using session and then destroyed
* flash.now => will be used in the current request only
* flash.keep(...) => will preserve the current or chosen variables to the next request
%Filters
-> before, after, around
-> naming convention: private method, *_filter
-> they can get a block or a class also, for more complicated cases
* :except, :only
filter is_logedin, :except => [login] # or :only...
-> prepend_before_filter, prepend_after_filter would prepend instead of append the filter to the filter chain
-> arround filters wrap the execution of the action using a yield (before and after)
%%Filter Inheritance
* skip_filter to not run a filter which is defined in the parent class
#--- ACTION VIEW ---#
#The template environment
* All instance variables of the controller
* flash, headears, logger, params, request, responce, session -> normally we use them just for debugging
* controller => the current controller object. these allows to call the controller methods
* base_path => the path to the base directory of the templates
%template types
* builder for xml
* erb for plain dynamic content with ruby
* rjs for js
# Generating Forms
form_for(:model) do |form|
form.label :name
form.text_field :name, :placeholder => "enter your name here ..."
form.label :color
form.radio_button :color, "red"
form.label :red
form.radio_button :color, "yellow"
form.label :yellow
form.radio_button :color, "green"
form.label :green
form.label "condiment"
form.check_box :ketchup
form.label :ketchup
form.check_box :mustard
form.label :mustard
form.select :priority, (1..10)
form.select("post", "category", Post::CATEGORIES, {:include_blank => true}) # => very flexible, other ways: http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html
form.date_select :start #=> very reach, e.g. distance_of_time_in_words_to_now, http://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html
form.time_select :alarm
form.
* search_field
* telephone_field
* url_field
* email_field
* number_field
* range_field
* hidden_field
* password_field
... http://edgeguides.rubyonrails.org/form_helpers.html
-> use placeholder as above
# Processing Forms
-> POST: user[name]=rrr will result in a hash user={:name => "rrr"}
user.update_attributes(params[:user])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment