`
andyhu1007
  • 浏览: 199482 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Rails每周闲碎(二): Model

阅读更多

1. model validates

 

    Rails的model提供了多种validate方法。 比如:

 

    validates_acceptance_of :terms_of_service    # 对于checkbox的印证,再合适不过了。

 

    validate_confirmation_of  #password confirmation

 

    validates_associated  #对assocation的validates。

 

    在save过程中,model的validates先于before_save, before_create这些callback被调用。

 

    我们还可以定置自己的validate方法:

 

    validates_positive_or_zero :number  #在lib/validations.rb里面加上这个方法即可。

 

    或者 validates :your_method  #在这个methods里面加上印证,如果失败,往erros里面添加错误信息。

 

 

2. ActiveRecord的callbacks

 

       要注意各个callback的正确使用,比如:  不要指望after_create保存在对象上所做的改变,除非你显式调用save。因为after_create的调用是在base.save之后。

 

 

      after_initialize, after_find

 

      http://guides.rubyonrails.org/activerecord_validations_callbacks.html#after-initialize-and-after-find

 

      This behaviour is due to performance reasons, since after_initialize and after_find will both be called for each record found in the database, significantly slowing down the queries.

 

      save & validation

 

      Rails ActiveRecord callback sequence  validation callback is before save callback

 

3. Association

 

    has_many和has_one的validate默认值不同。

 

    比如有两个对象之间的关联是这样的:

 

 

class Company

    has_many :people
    has_one :address

end

 

    当我们在controller里面这样创建它们时:

 

def create

   @person = Person.new(params[:person])
   @company = Company.new(params[:person][:company])
   @address = Address.new(params[:person][:company][:address])

   @company.people << @person
   @company.address = @address
   
   @company.save!
   
end

 

    不要以为address会被验证,其实对于has_one关联,默认的validate为false。

 

    所以,我们要显示得指定:

 

has_one :address, :validate => true

 

 

    注意has_one 和 belongs_to的外键所在:

 

    has_one关联,对应的外键在对方表中; belongs_to关联,外键在自身表中。

 

4. Attributes

 

 

   attributes_protected  attributes_accessible

 

    如果你想让某些值可以被mass assign,比如这样person = Person.new(params[:person]),那么你得把它们声明在attributes_accessible里。当然,你也可以不声明任 何的attributes,不过这样会给你带来可能的安全问题。

 

    显而易见,如果只有少部分attributes不允许被mass assign,那么把这些放在attributes_protected里更加方便。

 

 

 

    ActiveRecord::Base中的inspect方法

 

   看源码

 

 

# File vendor/rails/activerecord/lib/active_record/base.rb, line 2850
def inspect
       attributes_as_nice_string = self.class.column_names.collect { |name|
        if has_attribute?(name) || new_record?
             "#{name}: #{attribute_for_inspect(name)}"
          end
         }.compact.join(", ")
        "#<#{self.class} #{attributes_as_nice_string}>"
en
 

 

    明白了么,如果是不在数据库中的attribute,它是不会打出来给你看的~~~

 

 

    Boolean column:

 

    Rails does a nifty thing with boolean columns: it supports the Ruby question mark convention for object attributes that return a boolean Ruby value.

 

    Type attribute:

 

    为什么不能用self.type?因为type是ruby的保留方法,它会返回类型信息。所以,要取得对象内的type attribute,就得用self[:type]。可以看出,所有的attributes,都可以用hash的方式取出。

 

 

 

5. Find方法中的select option

 

    有时候为了执行效率,我们会指定select的字段。对于纯粹的数据读取,这没问题。但如果还会对读取之后的数据进行更新,则需要注意,不要在select中落下id字段。

 

    比如:

 

person = Person.find(:first, :select => "first_name, last_name")
person.update_attribute :first_name, person.first_name.downcase

 

    你会发现第二个语句的执行sql是:

 

update people set first_name = 'bo' where id = nil

 

    这会导致对person的更新不能成功。

 

    正确的操作是:

 

person = Person.find(:first, :select => "id, first_name, last_name")
person.update_attribute :first_name, person.first_name.downcase

 

 

 

    则更新操作就会成功:

 

update people set first_name = 'bo' where id = 12

 

 

6. save(false), save and save!

 

    save(false): skip model validation

    save: donot skip model validation

    save!: raise exception if not valid, create! called it

 

7. new_record?

 

 

      # Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet.
      def new_record?
        defined?(@new_record) && @new_record
      end

 

 

8. destory, delete

 

    destory: Deletes the record in the database and freezes this instance to reflect that no changes should be made. And particularly, it can set callbacks through before_destroy and after_destroy.

    delete: it simply delete the row in database and freeze the instance. But it does not have any callbacks unless you make it by observers. If you do want callbacks, use destroy.

 

    对于依赖删除的model,如果只是想让关联失效,而不是删除记录,可以使用:nilfy指定。

 

9.  乐观锁,悲观锁机制

 

   http://guides.rubyonrails.org/active_record_querying.html#locking-records-for-update

 

10. Eager loading and N +1

 

 

clients = Client.all(:limit => 10) 
clients.each do |client| 
  puts client.address.postcode 
end 
 

    11 queries

 

     VS

 

 

clients = Client.all(:include => :address, :limit => 10) 
clients.each do |client| 
  puts client.address.postcode 
end 

 

    2 queries:

 

 

SELECT * FROM clients 
SELECT addresses.* FROM addresses WHERE (addresses.client_id IN (1,2,3,4,5,6,7,8,9,10)) 

 

    http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations

 

11. named_scope

 

    定制一个具名的find方法:http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html#M002177


12. accepts_nested_attributes_for

 

    Make complex form easier.   http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#M002132

 

 

 

3
0
分享到:
评论

相关推荐

    Rails的精简版本Rails::API.zip

    Rails::API 是 Rails 的精简版本,针对不需要使用完整 Rails 功能的开发者。 Rails::API 移除了 ActionView 和其他一些渲染功能,不关心Web前端的开发者可更容易、快速地开发应用程序,因此运行速度比正常的 Rails ...

    Ruby on Rails入门例子

    Ruby on Rails,简称Rails,是一种基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本篇将通过一个入门实例,深入探讨Rails的基本概念和核心...

    Rails上的API:使用Rails构建REST APIAPIs on Rails: Building REST APIs with Rails

    ### 二、为什么选择Rails来构建RESTful API 1. **快速开发**:Rails内置了许多实用的功能和库,如ActiveRecord ORM、MVC架构等,这些都能够极大地加快开发进度。 2. **代码简洁**:Rails遵循“约定优于配置”的原则...

    rails-ansible-presentation:有关Rails + Ansible的Deckset演示

    [适合] Rails :red_heart: Ansible [适合] Rails :red_heart: Ansible (有一点帮助) Rails部署 简单吧? 将应用程序放在服务器上。 捆绑宝石。 应用迁移。 重新启动服务。 Easy Rails部署 git push master ...

    rails-basic-template:基本 Rails 模板

    Rails 基本模板参考: : Ruby on Rails Gemfile:定义应用程序正在使用的库的文件bundle install:基于Gemfile,安装所有库每次修改 Gemfile 时都应该运行bundle install gem 是 Ruby 的库RubyGems.org 是一个查找和...

    Ruby on Rails入门经典代码

    Ruby on Rails,简称Rails,是基于Ruby语言的一个开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本压缩包中的"Ruby on Rails入门经典代码"提供了新手学习...

    rails_console_toolkit:可配置的 Rails 控制台助手

    RailsConsole 工具包 :wrench: :toolbox: 可配置的 Rails 控制台助手更快地查找记录,添加自定义助手,将您的控制台寿命提高 100%。安装将此行添加到应用程序的 Gemfile 中: gem 'rails_console_toolkit' 然后生成...

    webpack-rails, 将 web pack与你的Ruby on Rails 应用程序集成.zip

    webpack-rails, 将 web pack与你的Ruby on Rails 应用程序集成 不再维护webpack-rails 不再被维护。 有关详细信息,请参阅 #90. web pack-railsweb pack 为你提供了将 web pack集成到现有的Ruby on Rails 应用程序中...

    rails_email_preview:在Rails中预览和编辑应用程序邮件模板

    Rails电子邮件预览 使用此Rails引擎在浏览器中预览电子邮件。 与Rails 4.2+兼容。 一封电子邮件评论: 所有电子邮件预览的列表: REP带有两个主题:一个简单的独立主题和一个使用的主题。安装加 到Gemfile: gem '...

    rails-dom-testing:从ActionView中提取DomAssertions和SelectorAssertions

    Rails :: Dom :: Testing 这个gem负责比较HTML DOM并断言Rails应用程序中存在DOM元素。 assert_dom_equal通过assert_dom_equal和assert_dom_not_equal进行比较。 元素通过assert_dom , assert_dom_encoded , ...

    Rails相关电子书汇总二

    标题 "Rails相关电子书汇总二" 提供的信息表明,这个压缩包包含的是一些关于Rails框架的高级主题的电子书籍资源。Rails是一个流行的开源Web应用框架,基于Ruby编程语言,它遵循模型-视图-控制器(MVC)架构模式,为...

    Rails中应用Ext.tree:以中国的省市地区三级联动选择为例

    rails generate model City province_id:integer name:string rails generate model District city_id:integer name:string ``` 然后,通过运行`rails db:migrate`来执行数据库迁移。 在模型定义完成后,作者会...

    rails有用的命令

    - `$ rails g model ModelName attributes`:创建一个新模型,如ModelName,并指定其属性。 以上就是Rails中一些常用的命令和概念,它们构成了Rails开发的基础。理解并熟练掌握这些命令,能大大提高开发效率。在...

    rails-controller-testing:将`assigns`和`assert_template`带回到您的Rails测试中

    Rails :: Controller :: Testing 这个gem将assigns给控制器测试的内容以及assert_template带回assigns控制器和集成测试的内容。 这些方法已中。 安装 将此行添加到您的应用程序的Gemfile中: gem 'rails-...

    rails_stack-cookbook:使用 nginx、unicorn、redis 等设置 Rails 环境的 Chef 食谱

    rails_stack 食谱 TODO:在此处输入食谱说明。 例如,这本食谱使您最喜欢的早餐三明治。 要求 TODO:列出您的食谱要求。 确保包含本说明书对平台、库、其他说明书、软件包、操作系统等的任何要求。 例如 包裹 ...

    rails-cache-extended:帮助程序和日志记录添加到 Rails 缓存

    Rails::Cache::Extended 这允许为记录集合生成自动过期的缓存键 安装 将此行添加到应用程序的 Gemfile 中: gem 'rails-cache-extended' 然后执行: $ bundle 或者自己安装: $ gem install rails-cache-...

    vite_rails:Rails中的:high_voltage:Vite.js,为您JavaScript体验带来欢乐

    允许您使用为Rails应用程序的前端供电。 是将前端工具像Ruby一样进行编程,纯属喜悦! :smiling_face_with_heart-eyes: 或在运行的检查。 产品特点 :high_voltage: :light_bulb: 即时服务器启动 :high_voltage: ...

    atom-rails-db-scheme:Rails数据库模式的Autocomplete +提供程序

    Rails数据库方案 Rails数据库模式的Autocomplete +提供程序。 特征 自动完成活动记录 根据当前上下文打开模式文件 设定值 将Rails语法设置为默认语法。 " * " : core : customFileTypes : " source.ruby.rails...

    rails-html-sanitizer

    如果您在非Rails应用程序中需要类似的功能,请考虑直接使用(这是处理内幕消毒的原因)。 安装 将此行添加到您的应用程序的Gemfile中: gem 'rails-html-sanitizer' 然后执行: $ bundle 或将其自己安装为: $...

Global site tag (gtag.js) - Google Analytics