zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    A Simple Problem with Integers poj 3468 多树状数组解决区间修改问题。
    Fliptile 开关问题 poj 3279
    Face The Right Way 一道不错的尺取法和标记法题目。 poj 3276
    Aggressive cows 二分不仅仅是查找
    Cable master(二分题 注意精度)
    B. Pasha and String
    Intervals poj 1201 差分约束系统
    UITextField的快速基本使用代码块
    将UIImage转换成圆形图片image
    color转成image对象
  • 原文地址:https://www.cnblogs.com/wangyuyu/p/3235389.html
Copyright © 2011-2022 走看看