rails 中 create, new, build, save 的用法以及誤區匯總 (轉)


自己很初級,初級的不能再初級,所以初次接觸rails的時候,對於里面的create,new,build等方法不是很了解,用的很混亂,導致經常出現不必要的bug,很苦惱,決定,總結一下,結合網上已有資源,深入理解下 向數據庫插記錄時經常會用到new, build, create。這三個方法很容易混淆
save:rails中的save其實是create_or_update,新建或修改記錄!不一定是新建,切記 new :只是在內存中新建一個對象,操作數據庫要調用save方法。 create = new + 執行sql。 build:與new基本相同,多用於一對多情況下。還有一個不同請看使用示例 !:new!, create!, build!與new, create, build的區別是帶!的方法會執行validate,如果驗證失敗會拋出導常。 save是實例方法,而create, build, new是模型類的類方法
還有另外一種說法,也挺好,如下     首先說new吧,app = App.new(params[:app]),這個是用給定的params來實例化一個app對象,注意此時只是初始化了一個對象,ruby只是在內存里面給app分配了一個內存地址,但是,這 個地址還沒有指定任何的有效的內存,所以接下來ruby要做的就是調用model里面的initialize函數來根據給定的參數進行初始化這個對象,並將該對象保存到堆里面。     對於new!來說,這個跟new相比,就是在save到數據庫的時候,如果save失敗,就會報一個錯誤。     對於create來說,過程大致跟new差不多,唯一的區別是,create = new + save,即create一步操作等於new和save的兩部操作。     對於create!來說,類似於new! 過程大致也是跟new!差不多 區別是create! = new! + save  如果保存失敗的話會返回一個錯誤。     對於build來說,主要的混淆的地方在於與new的區別,其實,我認為build是new的一個別名,但是用的地方可能跟new有點區別,在我看來,build大多是用於有關聯關系的對象模型的時 候,用來創建子model用的,比如說 Person  與 Order是一對多的關系,那么我們可以用 @persion.build()方法來創建於該person對應的orders

 

下面有一個簡單的示例:

 

  1. 本來是想用accepts_nested_attributes_for寫一個nested form 
本來是想用accepts_nested_attributes_for寫一個nested form
  1. class User < ActiveRecord::Base 
  2.   attr_accessible :email, :account_attributes 
  3.   has_one :account 
  4.   accepts_nested_attributes_for :account 
  5. end 
  6.  
  7.  
  8. class Account < ActiveRecord::Base 
  9.   attr_accessible :password, :password_confirmation 
  10.   has_secure_password 
  11.   belongs_to :user  
  12. end 
  13.  
  14.  
  15. class UsersController < ApplicationController 
  16.   defnew 
  17.     @user = User.new 
  18.   end 
  19. end 
class User < ActiveRecord::Base
  attr_accessible :email, :account_attributes
  has_one :account
  accepts_nested_attributes_for :account
end


class Account < ActiveRecord::Base
  attr_accessible :password, :password_confirmation
  has_secure_password
  belongs_to :user 
end


class UsersController < ApplicationController
  def new
    @user = User.new
  end
end

 

view里

 

  1. <%= form_for @userdo |f| %> 
  2.   email: <%= f.text_field :name %> 
  3.   <%= f.fields_for :accountdo |account_form| %> 
  4.     password: <%= account_form.password_field :password %> 
  5.     password_confirmation: <%= account_form.password_field :password_confirmation %> 
  6.   <% end %> 
  7. <% end %> 
<%= form_for @user do |f| %>
  email: <%= f.text_field :name %>
  <%= f.fields_for :account do |account_form| %>
    password: <%= account_form.password_field :password %>
    password_confirmation: <%= account_form.password_field :password_confirmation %>
  <% end %>
<% end %>
一開始無法顯示account里的內容,后來發現沒有在controller里build account, 於是

 

 

  1. class UsersController < ApplicationController 
  2.   defnew 
  3.     @user = User.new 
  4.     @user.account.build 
  5.   end 
  6. end 
class UsersController < ApplicationController
  def new
    @user = User.new
    @user.account.build
  end
end
報錯 undefined method `build' for nil:NilClass
剛開始怎么也想不通,隔了一天去翻http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html 才發現原來has_one的build方法是build_association而不是collection.build。因為不常用has_one,rails里“約定”又比較多,才會當has_many的方法來寫。
把controller里改成

 

 

  1. class UsersController < ApplicationController 
  2.   defnew 
  3.     @user = User.new 
  4.     @user.build_account 
  5.   end 
  6. end 
class UsersController < ApplicationController
  def new
    @user = User.new
    @user.build_account
  end
end

 

 

程序才正常跑起來
一言蔽之 在has_many中:User#accounts.build 在has_one中:User#build_account


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM