[Rails] Soup to bits
1. Install Ruby: http://rubyinstaller.org/
2. Install Rails: http://railsinstaller.org/en
3. Open RubyMine, using cmd to create a new project called "soup_to_bits"
4. cd into the proejct and run the cmd below, it will install all what you need to project
bundle install
5. run the rails server:
rails server
6. Check localhost:3000 to see the welcome interface.
----------------- Create a Model-----------------
1. create a Soup model:
rails generate model Soup name:string featured:boolean category_id:integer
2. create a Category model:
rails generate model Category name:string
Create:
rails generate model Soup name:string featured:boolean category_id:integer
Delete:
#rails destroy model <model name>
rails destroy model Soup
----------------End of Model---------------------
----------------Start database------------------
run:
rake db:migrate
== 20140917163603 CreateSoups: migrating ======================================
-- create_table(:soups)
-> 0.0010s
== 20140917163603 CreateSoups: migrated (0.0010s) =============================
== 20140917164909 CreateCategories: migrating =================================
-- create_table(:categories)
-> 0.0010s
== 20140917164909 CreateCategories: migrated (0.0020s) ========================
----------------End of database------------------
--------------------On model------------------
1. run: go to the rails console
rails console
2. Do something on the Soup
s.name = "Tonkotsu" s.featured = true s.save
Soup.create(name: "Tomato Bisque", featured: false) Soup.last # check the newest inserted Soup.all # check all
Soup.create(name:"French Onion")
3. Find a soup:
#1. using Where to get back an array s = Soup.where(name: "Tonkotsu").first #2. using Find to get the soup s = Soup.find(1) #3. using Find by name to get the soup s = Soup.find_by_name("Tonkotsu")
4. Update a soup:
s.update(fretured: true)
s.fretured = true
s.save
5. Delete soup:
Soup.last.destroy
----------------------End on Model------------------------
---------------------Start relationship -------------------
1. open the soup.rb and categroy.rb
write in soup.rb:
class Soup < ActiveRecord::Base belongs_to :category end
write in categroy.rb:
class Category < ActiveRecord::Base has_many :soups end
2. reload the console: to make the relationship works:
reload!
3. make a category:
Category.create(name: "Bouillon") Category.create(name:"Ramen")
4. Assign soup to cateory:
s = Soup.last s.category = Category.last s.save
5 .<<
s = Soup.create(name:"Beef Flavor") c = Category.last c.soups << s # this will save automaticlly
6. Prevent an empty soup
class Soup < ActiveRecord::Base belongs_to :category validates :name, presence: true, uniqueness: true end
Remember to reload!
Then when create an empty soup, it will says:
irb(main):110:0> Soup.create ←[1m←[35m (0.0ms)←[0m begin transaction ←[1m←[36mSoup Exists (0.0ms)←[0m ←[1mSELECT 1 AS one FROM "soups" WHERE "soups"."name" IS NULL LIMIT 1←[0m ←[1m←[35m (1.0ms)←[0m rollback transaction => #<Soup id: nil, name: nil, featured: nil, category_id: nil, created_at: nil, updated_at: nil>
We can check the errors messages for the resason:
#For example we want to do: s = Soup.create # create an empty data # it will fail s.errors.messages # to check the message
Any time you forget the snytax for the code, go the link:
http://guides.rubyonrails.org/active_record_querying.html
---------------------End relationship -------------------
---------------------Start Route--------------------
in config/routes.rb:
Rails.application.routes.draw do
resources :categories, :soups
end
---------------------End relationship -------------------
---------------------Start Controller--------------------
1. Generate the controller
#cmd rails generate controller Soups rails generate controller Categories
2. go to the link: http://localhost:3000/categories
Then we see the page shows error.
So we should go on to create index action in categories controller
def index end
Again here we get the errors:
Shows to we dont have tempate to show the content.
Therefore, add an index.html.erb into views/categorie floder:
#index.html.erb <h1>Soup Categories</h1>
Now, everything works fine:), we can see the h1 tag on the page.
----------------------------------------------------------------------------
More stuff come in
- List all the categories and when click the link will navigate to the detail page.
- From the detal category page can link back to all categories page.
- Show the total soups number for earch category
- When click on each soup, link to soup detail
categories_controller.rb
class CategoriesController < ApplicationController def index @categories = Category.all end def show @category = Category.find(params[:id]) end end
views/categories/index.html.erb
<h1>Soup Categories</h1> <ul> <% @categories.each do |category| %> <li><%= link_to category.name, category %> (<%= category.soups.count %>)</li> <% end %> </ul>
views/categories/show.html.erb
<h1><%= @category.name %></h1> <ul> <% @category.soups.each do |soup| %> <li><%= link_to soup.name, soup %></li> <% end %> </ul> <p><%= link_to "Back", categories_path%></p>
If sometime you forget which route you cna use: to check
#cmd rake routes
soups_controller.rb
class SoupsController < ApplicationController def show @soup = Soup.find(params[:id]) end end
views/soups/show.html.erb
<h1>This is <%= @soup.name %> Soup</h1> <% if @soup.featured? %> <p>This delicious soup is featured this month.</p> <% else %> <p>This soup is not in season</p> <% end %>
------------------------------------------------------------
Make soup return as json foramt
In controller:
def show @soup = Soup.find(params[:id]) respond_to do |format| format.html # default format format.json {render json: @soup} end end def index respond_to do |format| format.json {render json: @soups} end end
--------------------------------------------------------
DRY:
For example, you our categories controller, we have defined
show, new, edit, destory methods
Each of those methods will do one same thing is:
@soup = Soup.find(params[:id])
That's very DRY!
What we can do is to use before_action to handle this code and what it does is before each action which you specific will, it do the pre-progress you require.
before_action :fetch_soup, only: [:show, :eidt, :destory, :update] private def fetch_soup @soup = Soup.find(params[:id]) end
--------------------------------------------------------
More in routing:
check: http://guides.rubyonrails.org/routing.html#redirection
- When user into localhost:3000, it should redirect to categories controller index action.
- If user input allcategories, then redirect to root
resources :categories, :soups root to: "categories#index" get "/allcategories" => redirect("/")
-----------------------------------------
Toggle the feature:
- When I click the toggle button, it will toggle the feature on the soup
#routes.rb get "/soups/:id/toggle_featured", to: "soups#toggle_featured", as: "toggle_featured"
soups_controllers.rb
before_action :fetch_soup, only: [:show, :eidt, :destory, :update, :toggle_featured] def toggle_featured @soup.toggle!(:featured) redirect_to @soup end
Wrapper around toggle
that saves the record. This method differs from its non-bang version in that it passes through the attribute setter. Saving is not subjected to validation checks. Returns true
if the record could be saved.
-----------------------------------
Let user get noticed!
- Once featured is successfully changed, let user get noticed!
def toggle_featured @b = @soup.toggle!(:featured) # will turn true if record is saved if @b flash[:notice] = "Successfully changed the status" end redirect_to @soup end
application.html.erb
<% if flash[:notice] %> <p><%= flash[:notice] %></p> <% end %>
------------------------------------------
VIP Session:
- Now if user login as vip user: localhost:3000/vip, we use session to controll whether show secrect soup
#routes.rb
get "/vip", to: "soups#vip"
#soups_controller def vip session[:vip] = true redirect_to "/" end
#categories.index.erb <% if session[:vip] %> <li>Super Secret Bouillon</li> <% end %>
Check the Code on GitHub: https://github.com/zhentiw/ruby/
ALL DONE!!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具