Basic Rails Stuff
Slightly More Complicated
I Totally Invented Planking
In The Early 80's
# From The Command Line: rails generate controller Store index
# Generate a Model named Product (database table named products) # As well as a title, a description, an image URL, and a price column # # From The Command Line: rails g scaffold Product title:string description:text image_url:string price:decimal # Now apply the Migration. From the Command Line: rake db:migrate
# To delete "blog" scaffold, from the command line: rails destroy scaffold blog
# From The Command Line: rake db:rollback
# replace root_path with your path <%= form_tag root_path, :method => 'POST' do %> <%=label_tag 'First Name' %> <%=text_field_tag 'first_name'%> <%= submit_tag 'Submit' %> <% end %>
class WhateverController < ApplicationController def index @submitted_name = params[:first_name] end end
post "/" => 'whatever#index'
# From Command Line, check that Heroku Toolbelt is installed heroku --version # Enter email address and password to login to Heroku heroku login # Add your SSH keys heroku keys:add # Add a heroku app heroku create # Remove sqlite3 db from gemfile, add to development section of gemfile then bundle without dev bundle install --without development # Push Code git add . git commit -am "message" git push git push heroku master
#Add TinyMCE gem to gemfile to create a wordpress editor on blog creation/writing pages. # Use .html_safe tag on output variables so the HTML gets executed
<% flash.each do |name, msg| %> <div class="alert alert-warning alert-dismissible"> <button class="close" data-dismiss="alert"> <i class="glyphicon glyphicon-remove-circle"></i> </button> <%= content_tag(:div, msg) %> </div> <% end %>
# From your app/models/whatever.rb file add the line: validates :title, :description, :image_url, presence: true # where :title, :description, etc are your form fields
validates :price, numericality: {greater_than_or_equal_to: 0.01}
validates :title, uniqueness: true
validates :image_url, allow_blank: true, format: { with: %r{\.(gif|jpg|png)\Z}i, message: 'must be a URL for GIF, JPG or PNG image.' }
# In...say...a home_controller.rb file class HomeController < ApplicationController # Specify Which Actions Can Use Your Common Content before_action :common_content, :only => [:index, :show] def common_content @random_number = (1..100) end def index end def show end # now you can use the @random_number instance variable on the index.html.erb and show.html.erb view pages
# From Your app/controllers/whatever_controller.rb def index @products = Product.order(:title) end
<% @products.each do |product| %> <%= image_tag(product.image_url) %> <h3><%= product.title %></h3> <%= sanitize(product.description) %> <%= product.price %> <% end %>
# From /config/environments/development.rb enable cache then restart server config.action_controller.perform_caching = true
class Product < ActiveRecord::Base . . def self.latest Product.order(:updated_at).last end end
# above product loop: <% cache ['store', Product.latest] do %> . #under product loop <% cache ['entry', 'product'] do %> . . <% end %> <% end %>
# where (:item) is the variable you want in your url and the ()'s make it optional get 'home/index(/:item)' => "home#index" # or for more than one item: get 'home/index(/:category(/:item))' => "home#index"
# create instance variable @item = params['item'] # check to see if an item was listed if @item == nil # do nothing else # replace and underscores _ with blank spaces @item = @item.gsub(/_/, " ") end
http://yourURL.com/home/index/fender_deluxe_stratocaster_guitar
# Routes file: get '(/:category(/:item))', to: "home#index" # Then do the same controller stuff in your home/controller # And the output URL will look like this: http://yourURL.com/guitars/fender_deluxe_stratocaster_guitar # Where your @category instance variable will be "guitars" # and your @item instance variable will be "fender deluxe stratocaster guitar"
# From The Command Line: rails generate migration AddSomethingToTablename addsomething:string # Where AddSomething is the thing you want to add and Tablename is the table you're adding too rake db:migrate # Note: You then have to update your views and controller manually for CRUD actions # # To add several things: rails generate migration AddFieldsToTablename first_name:string last_name:string age:integer # then rake db:migrate # #To Remove a Column rails g migration remove_field_name_from_table_name field_name:datatype
# To Roll back the last migration, From The Command Line: rake db:rollback # To Roll back some other previous migration (where n is the number back you want to go...) rake db:rollback STEP=n
# From db/seeds.rb Whatever.create ([:user_name => "myName#{rand(1..100)}", :first_name => "John", :last_name => "Elder", :age => "38", :description => "blah blah blah" ]) # Where Whatever is your db table, and the :first_name etc fields are your database columns found in your schema file # and #{rand(1..100)} creates a random number so the username is unique every time we seed (and fools any validation) the database! # From the Command Line: rake db:seed
#Add to gemfile: gem 'linguistics' gem 'faker' # then bundle install from command line
# Let's create 100 records 100.times do Whatever.create ([:user_name => "#{Faker::Internet.user_name}", :first_name => "#{Faker::Name.first_name}", :last_name => "#{Faker::Name.last_name}", :age => "#{rand(15..120)}", :description => "#{Faker::Lorem.paragraph}" ]) end # From the Command Line: rake db:seed
# Where Whatever is the name of your database table Whatever.destroy_all # Easy => Slap Whatever.destroy_all into your seeds.rb file and then rake db:seeds, or do it from the console
# Pull up Rails Console From Terminal rails console # Pull in database called User: User.connection # Show all records User.all # See first record User.first # See last record User.last # Count records User.count # Search records User.where(:last_name => "Elder") # Change something in a record, like first_name (set user into a variable) a = User.first # Make your changes a.first_name = "Bob" # Save the change to the database a.save # Delete all records in the database (but don't delete the table) User.destroy_all
# Say we have a Blog model and want to create a Comment model for comments. From command line: rails generate scaffold Comment title:string author:string content:text blog:references # Where blog:references is the foreign key that associates the Comment model with the Blog model rake db:migrate #Run the migration
belongs_to :blog
has_many :comments, :dependent => :destroy #:dependent => :destroy tells rails to delete comments if you delete a blog post
# Let's create 100 records 100.times do Blog.create ([:user_name => "#{Faker::Internet.user_name}", :first_name => "#{Faker::Name.first_name}", :last_name => "#{Faker::Name.last_name}", :age => "#{rand(15..120)}", :description => "#{Faker::Lorem.paragraph}" ]) blog.save rand(0..10).times do Blog.comments.create([:title => "#{Faker::Internet.user_name}", :author => "#{Faker::Name.first_name}", :comment => "#{Faker::Name.last_name}" ]) end end # From the Command Line: rake db:seed
<% blog.comments.each |comment| do %> <h3><%= comment.title %></h3> <h3><%= comment.author %></h3> <p><%= comment.content %></p> <hr/> <% end %>
# You can grab the form from the comments scaffold and past it onto your blog show page # But you need to post the form and associate it with the blog post at the same time for @comment <%= form_for(@comment) do |f| %> . . # change the blog_id form field to hidden . . <% end%>
def show @comment = Comment.new end
# in routes.rb move resources :comments line into nested resources :blog do block resources:blog do resources :comments end
# on your blog show view, add @blog reference (notice the array [ ]) <%= form_for([@blog, @comment]) do |f| %> . . <% end%>
def create @blog = Blog.find(params[:blog_id]) @comment = @blog.comments.new(comment_params) # @comment = Comment.new(comment_params) # Then Save and Redirect, but not to @comment, we want to redirect to @blog respond_to do |format| if @comment.save format.html { redirect_to movie_path( @blog ), notice: "Comment was successfully created." } format.jason { render action: 'show', status: :created, location: @comment} else format.html { redirect_to movie_path( @blog ), notice: "Comment was not created." } format.jason { render json: @comment.errors, status: :unprocessable_entity } end end end
# From your app/models/whatever.rb file validates :description, presence: true, length: { maximum: 140 } validates :user_name, presence: true, uniqueness: true
# On Each Page/View of Your Site... <% content_for :title, "Your Unique Title" %> # Then in your layouts/application.html.erb file... <!DOCTYPE html> <html> <head> <title><%= yield(:title) %></title> . . .
# In Your Routes file... resources :blogs, path: "whatever" # Now your route would be www.yoursite.com/whatever/6 instead of yoursite.com/blogs/6
# In Your app/model/Model.rb file... def to_param # change spaces in title to hyphens - title.gsub!(/\s/,'-') #change URL from ID to ID-Title "#{id}-#{title}" end
# In Your app/model/Model.rb file... def to_param # change spaces in title to hyphens - title.gsub!(/\s/,'-') #change URL from ID to Title "#{title}" end
# In Your Routes file... resources :blogs, path: '' #, param: :title # path: '' changes the path to root url
# In Your Controller... private # Use callbacks to share common setup or constraints between actions. def set_blog #replace spaces in title with hyphens @spaces = (params[:title]) @spaces.gsub!('-',' ') # find the blog post to output using find_by_title instead of just find #@blog = Blog.find_by(title: (params[:title])) #@blog = Blog.find_by_title(params[:id]) @blog = Blog.find_by_title(@spaces) end