教程積累

1.rails中使用bootstrap
2.局部變量和塊
3.flash用法
4.email.downcase
5.對(duì)象屬性
6.限制方法
7.改變淘寶源
8.send email
9.if語(yǔ)句使用賦值語(yǔ)句
10.使用tag
11.Kernel中的module function
12.render partial

1.rails中使用bootstrap

#gemfile中添加gem
gem 'bootstrap-sass'

#定義自定義的custom.css.scss
#如上文件中,添加如下代碼,這兩行代碼會(huì)引入bootstrap框架
@import "bootstrap-sprockets";
@import "bootstrap";

#下拉框生效
#application.js中引入bootstrap的javascript庫(kù)
//= require bootstrap

2.局部變量和塊

局部變量可以被代入塊中,但是塊中的局部變量不能被帶出塊的作用范圍內(nèi),其實(shí)這是閉包的知識(shí)
class Demo
  number = 2

  define_method :my_method do
    puts number
    person = "this is the demo"
  end

  Demo.new.my_method
  puts person
end
#上面的代碼執(zhí)行結(jié)果如下:
#2
#undefined local variable or method 'person'

3.flash用法

class PostsController < ActionController::Base 
  def create # save post 
    flash[:notice] = "Post successfully created" 
    redirect_to @post 
  end 

  def show 
  end
end

#show.html.erb 
<% if flash[:notice] %> 
  <div class="notice">
    <%= flash[:notice] %>
  </div> 
<% end %>

4.email.downcase

疑惑:是第二個(gè)email是何種表示形式,是一個(gè)局部變量,還是一個(gè)方法
before_save{self.email = email.downcase}

追根溯源,在這本書(shū)的第四個(gè)章節(jié),找到這段代碼的最初解釋:
class Word < String 
  # 如果字符串和反轉(zhuǎn)后相等就返回 true
  def palindrome?
    self == self.reverse # self 代表這個(gè)字符串本身
  end
end

s = Word.new("level") # 創(chuàng)建一個(gè) Word 實(shí)例,初始值為 "level"
s.palindrome? # => true

根據(jù)第四章的解釋,self代表的就是對(duì)象本身,在類中調(diào)用方法或訪問(wèn)屬性時(shí)可以不用 self(賦值時(shí)不行)。
下面的語(yǔ)句是等價(jià)的:
self == self.reverse
self == reverse

下面的兩條語(yǔ)句也是等價(jià)的:
#左側(cè)的self是必須,右側(cè)的self是可選的
self.email = email.downcase
self.email = self.email.downcase

為什么左邊的self是必須的,如果沒(méi)有 self,創(chuàng)建的是一個(gè)局部變量。
使用 self 的目的是確保把值賦給用對(duì)象屬性。

在元編程的書(shū)(中文第二版p220):
class MyClass
  attr_accessor :my_attribute

  def set_attribute(n)
    my_attribute = n
  end
end

obj = MyClass.new
obj.set_attribute(10)
obj.my_attribute  #=>nil

其中這條語(yǔ)句:

my_attribute = n

不確定是想給局部變量賦值,還是調(diào)用名為my_attribute=的擬態(tài)方法
在沒(méi)有確定答案的情況下,Ruby默認(rèn)選擇第一種方法,它定義了一個(gè)名為my_attribute的局部變量。
為了避免這個(gè)問(wèn)題,給當(dāng)前對(duì)象的屬性賦值時(shí),應(yīng)該顯性地使用self,代碼如下所示:

class MyClass
  attr_accessor :my_attribute

  def set_attribute(n)
    self.my_attribute = n
  end
end

obj = MyClass.new
obj.set_attribute(10)
obj.my_attribute  #=>10

這也是為什么在上面的代碼中,左側(cè)的self不能省略的原因。

5.對(duì)象屬性

對(duì)象的屬性:一個(gè)對(duì)象的外部可見(jiàn)部分被稱其為屬性。ruby通過(guò)對(duì)象的實(shí)例變量來(lái)表示對(duì)象的內(nèi)部狀態(tài),即,屬性。
既然是對(duì)外部可見(jiàn)的。Ruby中,實(shí)例變量無(wú)法直接為對(duì)象外使用,只能通過(guò)對(duì)象定義的操作方法訪問(wèn)。
同理,實(shí)例變量也不能變成public變量,同樣是通過(guò)方法訪問(wèn),那就是可以通過(guò)某種方式讀取和修改的。
Ruby中是通過(guò)定義方法來(lái)訪問(wèn)屬性。有兩種方法方式
1.直接定義類屬性的方法   
2.通過(guò)Module的方法定義

1.直接定義類屬性的方法:

#這個(gè)就是定義一個(gè)對(duì)象的實(shí)例變量name,作為T(mén)est的屬性     
class Test      
  def initialize(name)      
    @name=name      
  end
     
  def name      
    @name     
  end
     
  def name=(att)   
    @name=att   
  end  
end     

2.通過(guò)Module的方法定義

class Test
  attr_accessor :name
  #attr_accessor :"name"  #和上面的功能是一樣的,也能夠達(dá)到給@name賦值的效果

  def to_s
    "Test: #{@name}"
  end
end

#attr_accessor其實(shí)是設(shè)置了兩個(gè)實(shí)例方法,分別是“name=”和“name”方法,可以從如下的代碼中獲知:
Test.new.instance_methods.grep(/name/) #=>:name, :name=

#如果沒(méi)有執(zhí)行"name="方法,則下面的Test類對(duì)象的屬性值為nil
Test.new.instance_variables #=>[]

#如果執(zhí)行了“name=”方法,則相當(dāng)于賦值給了屬性@name
obj = Test.new
obj.name = "demo"
puts obj #=>Test:demo
obj.instance_variables #=>@name

6.限制方法

1.public:使用實(shí)例方法的形式進(jìn)行調(diào)用
2.private:不能顯式調(diào)用
3.protected:在同一個(gè)類中可以作為實(shí)例方法使用,但是其他地方無(wú)法使用

#public方法
默認(rèn)情況下public方法,除了initialize,它是一個(gè)private方法
#private方法
不能被顯式調(diào)用,可以其類或者子類中被隱式調(diào)用
class Demo
  def test
    private_test
  end

  private
    private_test
      puts "this is the private test"
    end
end

obj = Demo.new
obj.test #=>this is the private test

class Child<Demo
  def child_test
    private_test
  end
end
obj = Child.new
obj.child_test #=>this is the private test

#protected:在同一個(gè)類中(及其子類)可以作為實(shí)例方法使用,但是其他地方無(wú)法使用
class Point
  attr_accessor :x, :y
  protected :x=, :y=
  def initialize(x, y)
    @x, @y = x, y
  end

  def swap(obj)
    tempx, tempy = @x, @y
    @x, @y = obj.x, obj.y
    obj.x, obj.y = tempx,tempy #在同一個(gè)類中protected方法可以被調(diào)用
  end
end

p1 = Point.new(1,1)
p2 = Point.new(2,2)

p1.swap(p2)

puts p1.x  #返回2
p1.x = 10  #NoMethodError方法 #在類之外不能被調(diào)用

7.改變淘寶源

#查看淘寶源
gem sources -l

#移除https://rubygems.org源
gem sources -remove https://rubygems.org/

#增加http://ruby.taobao.org/源
gem sources -a https://gems.ruby-china.org

8.send email

#與controller的使用規(guī)則類似,在終端運(yùn)行下面的代碼
rails g mailer UserMailer

#在user_mailer.rb文件中建立如下的代碼:
class UserMailer < ApplicationMailer
  default from: "zhengjiajun121@gmail.com"
 
  def welcome_email
    mail(to: "zheng_jiajun@foxmail.com", subject: "Welcome to My Awesome Site")
  end
end

#建立兩個(gè)視圖文件,分別是welcome_email.html.erb文件和welcome_email.text.erb文件:

#進(jìn)行文件配置,在config/environments/developments.rb中添加如下代碼:

config.action_mailer.delivery_method = :smtp                  
config.action_mailer.smtp_settings = {                                   
  address: "smtp.gmail.com",                                             
  port: 587,                                                             
  user_name: "zhengjiajun121",                                           
  password: "xxx",                                                 
  authentication: "plain",                                               
  enable_starttls_auto: true } 

#在終端執(zhí)行下面的文件,郵件可以從gmail郵箱發(fā)送至foxmail郵箱中:
UserMailer.welcome_email.deliver_now

9.if語(yǔ)句使用賦值語(yǔ)句

#if語(yǔ)句的通常表示形式是如下:
if condition then
  expressions
end

#在此基礎(chǔ)上可以添加elsif、else:
if condition then
  expressions
elsif condition then
  expressions
else
  expressions
end

#下面介紹另外一種形式的if表達(dá)式:
def current_user
  if(user = nil)
    "the user is nil"
  elsie(user = nil)
    "the other situation"
  end
end

puts current_user.nil?  #true

上面的代碼說(shuō)明,兩個(gè)條件表達(dá)式都不滿足,因此current_user方法的返回值是nil.

#上面代碼的變形如下:
def current_user
  if(user = "cc")
    "the user is nil"
  elsie(user = nil)
    "the other situation"
  end
end

puts current_user.nil?  #false

總結(jié):該篇文章只是說(shuō)明賦值語(yǔ)句也可以被作為條件表達(dá)式的邏輯判斷,其中邏輯判斷的值為賦值語(yǔ)句中被賦值的變量,如果該變量的值為nil或者false,則該邏輯判斷的值為false.
如果該變量的值為除了nil或者false之外的其他值,則該邏輯判斷的值為true.

#tutorial教程中代碼
def current_user
  if (user_id = session[:user_id]) 
    @current_user ||= User.find_by(id: user_id) 
  elsif (user_id = cookies.signed[:user_id])
    user = User.find_by(id: user_id) 
    if user && user.authenticated?(cookies[:remember_token])    
      log_in user 
      @current_user = user 
    end
  end 
end

10.使用tag

介紹has_and_belongs_to_many和has_many

1.使用has_and_belongs_to
#新建一個(gè)model
rails g model Tag name:string

#如果使用has_and_belongs_to_many方法,需要使用使用關(guān)聯(lián)表,因此migrate表中使用如下代碼:
class CreateTags < ActiveRecord::Migration
  def change
    create_table :tags do |t|
      t.string :name
      t.timestamps
    end

    #設(shè)置的表格是字母表靠前的排前面,比如post比tag靠前,同時(shí)不需要該表的id值,因此將id值設(shè)置為false.
    create_table :posts_tags, :id => false do |t|
      t.integer :post_id
      t.integer :tag_id
    end
  end
end

#建立和取消數(shù)據(jù)庫(kù)表
rake db:migrate
rake db:rollback VERSION=id值

#在兩個(gè)model中做相應(yīng)的聲明
class Post < ActiveRecord::Base
  has_and_belongs_to_many :tags
end

class Tag < ActiveRecord::Base
  has_and_belongs_to_many :posts
end

#在rails console中對(duì)文章進(jìn)行tag

rails console
#創(chuàng)建兩個(gè)tag
Tag.create(name: "beautiful")
Tag.create(name: "ugly")
#給首篇文章添加兩個(gè)tag
Post.first.tags << Tag.first
Post.first.tags << Tag.second

#使用has_and_belongs_to_many的特點(diǎn)是,建立了posts_tags表,但是沒(méi)有在建立相應(yīng)的model.

2.使用has_many through

class CreateTags < ActiveRecord::Migration
  def change
    create_table :tags do |t|
      t.string :name
      t.timestamps
    end
end

#同時(shí)建立tagging 這個(gè)model
rails g model Tagging post_id:integer tag_id:integer

#同時(shí)修改兩個(gè)model:
class Post < ActiveRecord::Base
  has_many :taggings
  has_many :tags, :through => :taggings
end

class Tag < ActiveRecord::Base
  has_many :taggings
  has_many: posts, :through => :taggings
end

class Tagging < ActiveRecord::Base
  belongs_to :posts
  belongs_to :tags
end

rails console
#創(chuàng)建兩個(gè)tag
Tag.create(name: "beautiful")
Tag.create(name: "ugly")
#給首篇文章添加兩個(gè)tag
Post.first.tags << Tag.first
Post.first.tags << Tag.second
Tagging.all #顯示有結(jié)果,能看到tag和post的關(guān)聯(lián)

#在Post這個(gè)model中建立查詢方法,查詢存在某個(gè)特定tag的post
def self.post(tag_name)
  #這個(gè)try方法是在tag對(duì)象上調(diào)用posts方法
  Tag.find_by(name: tag_name).try(:posts)
end

#然后在終端查詢存在某個(gè)tag的文章的時(shí)候,代碼如下所示:
rails console
Article.tag_with("ugly")

#使用另外的scope方法也可以實(shí)現(xiàn)如上的效果,使用scope的好處是該方法可以實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用:
scope :tag_with, lambda{ |tag_name| joins(:tags).where(" tags.name = ?", tag_name)}
scope :latter_with, lambda{ |time| joins(:taggings).where("taggings.created_at > ?", time)}

#在rails console中可以實(shí)現(xiàn)單獨(dú)調(diào)用,也可以實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用,見(jiàn)下面所示:
rails console
Post.tag_with("ugly") #scope方法單獨(dú)調(diào)用
Post.tag_with("ugly").latter_than(Time.now) #scope方法實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用

11.Kernel中的module function

#Kernel中方法的解釋
The Kernel instance methods are documented in class Object 
while the module methods are documented here. 

我對(duì)這句話的理解是Kernel的實(shí)例方法已經(jīng)在Object類中進(jìn)行了說(shuō)明
Kernel文檔中的方法實(shí)現(xiàn)了Module類中的module_function功能。

#module function方法
1.可以直接通過(guò)模塊名直接調(diào)用該方法。
2.該方法將會(huì)作為私有實(shí)例方法被隱式調(diào)用,因?yàn)镵ernel模塊被include到Object類中。

module Mod 
  def one
    "This is one" 
  end 
  module_function :one
end

class Cls 
  include Mod 
  def call_one 
    one 
  end
end

Mod.one  #=> "This is one"
c = Cls.new
c.call_one #=> "This is one"

#返回Kernel中私有實(shí)例變量的個(gè)數(shù),剛好是文檔中所示個(gè)數(shù):
Kernel.private_instance_method.size  #67

puts "this is private instance method"  #被main對(duì)象進(jìn)行隱式調(diào)用
Kernel.puts " the method can be called with the module as a receiver"

#其實(shí)send是Kernel的公開(kāi)實(shí)例方法
Kernel.public_instance_methods.grep(/send/) # [:public_send, :send]

12.render partial
將articles的提取出來(lái)/article/_article.html.erb,同時(shí)在/article/index.html.erb顯示如下代碼:

<%= render @articles%>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容