[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
 
toggle!(attribute)

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!!!

 

 

posted @   Zhentiw  阅读(221)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· 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工具
点击右上角即可分享
微信分享提示