支持的数据类型
- :binary
- :boolean
- :date
- :datetime
- :decimal
- :float
- :integer
- :primary_key
- :string
- :text
- :time
- :timestamp
产生生产环境的数据库
rake db:migrate RAILS_ENV=production
新建数据库
rake db:create
1. 新建model
$ rails g model Event name:string is_public:boolean capacity:integer
$ rake db:migrate
会生成events数据表
#####小知识
>```
rails g model NurseAid::NurseInfo
变为表 nurse_aid_nurse_infos ^_^
2. 新增数据
event = Event.new
event.name = "Ruby course"
event.description = "fooobarrr"
event.capacity = 20
event.save #如果不调用save方法,event的id为nil
方法二
event = Event.new( :name => "another ruby course", :capacity =>30 )
event.save
如果save出错可以查看错误,event.errors.full_messages(这是一个数组)
###3. 数据库查询
>```
event = Event.where( :capacity => 20).first
events = Event.where( ["capacity >= ?", 20] ).limit(3).order("id desc")
4.更新数据库
event.update_attributes({})
###5. 删除数据
>```
e.destroy
6. 数据库关联
关联类型
belongs_to
has_one
has_many
has_many :through
has_one :through
has_and_belongs_to_many
外键
#一个article可以有很多个comment
rails generate model Comment commenter:string body:text article:references
#创建的comments的表含有article_id字段,对应article的id字段
#更改article的model,当article被删除,comments会被删除
has_many :comments, :dependent => :destroy
------------------------------------------------------
产生的migrate文件如下
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.string :commenter
t.text :body
t.belongs_to :article
end
end
end
#其实很少用:references,一般自己手动建立表。然后手动关联
----------------------------------------------------
#更改routes.rb
resources :articles do
resources :comments
end
##生成表单,很少用
<%= form_for ([@article, @article.comments.build]) do |f| %>
##创建comment
@comment = @article.comments.create(...)
migrate初步
#创建表
def change
create_table :users do |t|
t.string :name
t.text :description
t.email :string
t.timestamps
end
end
#创建表users
#rails g model NurseAid::NurseInfo user_id:integer->自动加s
#filename--> ***_create_nurse_aid_nurse_infos.rb
class CreateNurseAidNurseInfos < ActiveRecord::Migration
def change
create_table :nurse_aid_nurse_infos do |t|
t.integer :user_id, default:0
t.timestamps
end
end
end
在没有执行rake db:migrate之前,你可以更改这个文件的内容
#rails g migration AddDutyToNurseAidNurseInfos duty:string
#filename --> **_add_duty_to_nurse_aid_nurse_infos.rb
class AddDutyToNurseAidNurseInfos < ActiveRecord::Migration
def change
add_column :nurse_aid_nurse_infos, :duty, :string, :default => "",:null=> false
end
end
##还可以生产索引
#rails g migration AddDutyToNurseAidNurseInfos duty:string:index
class AddDutyToNurseAidNurseInfos < ActiveRecord::Migration
def change
add_column :nurse_aid_nurse_infos, :duty, :string
add_index :nurse_aid_nurse_infos, :duty, :unique => true
end
end
##删除字段
#rails g migration RemoveDutyFromNurseAidNurseInfo duty
#Remove***FromNurseAidNurseInfo
class RemoveDutyFromNurseAidNurseInfos < ActiveRecord::Migration
def change
remove_column :nurse_aid_nurse_infos, :duty
end
end
##加外键
#rails g migration AddUserRfToProduct user:references
class AddUserRfToProducts < ActiveRecord::Migration
def change
add_reference :products, :user, index: true
end
end
#这个迁移会增加user_id字段,并建立索引
# 这个有问题 TODO
##创建联合数据表
#rails g migration CreateJoinTableCustomerProduct customer product
create_join_tables :products, :categories do |t|
t.index :product_id
t.index :category_id
end
#会创建联合数据表,表名为categories_products,这个数据表有两个字段category_id和product_id
在change中可以实用的方法有
- add_column
- add_index
- change_column
- change_table
- drop_table
- remove_column
- remove_index
- rename_column
如果你已经运行了rake db:migrate,如果现在你想更改migrate文件,必须运行rake db:rollback命令,修改完成后运行rake db:migrate
更改一个表
change_table :products do |t|
t.remove :description, :name
t.string :part_number
t.index :part_number
t.rename :upcode, :upc_code
end
create_table :products do |t|
#创建一个category_id列
t.references :category
end
运行SQL语句
def ****
execute <<- SQL
select * from .......
SQL
end
表之间相连(尽量显示写出来,不要用默认的约定)
class Order < ActiveRecord::Base
belongs_to :customer #表名为customers,belongs_to必须要用单数
#会在orders中必须有customer_id字段
#或者通过参数制定
#belongs_to :customer, :class_name=>"Customer", :foreign_key=>"customer_id"
end
class Supplier < ActiveRecord::Base
has_one :account #用单数,在accounts中必须有supplier_id字段
#可以通过制定一些参数,设置外键
#has_one :account :class_name=>"Account", :foreign_key=>"supplier_id"
#通过上面的设置可以设置和哪个Model的哪个字段相连
end
class Customer < ActiveRecord::Base
has_many :orders #用复数形式,在orders表中必须有customer_id
end
----------------------------------------------------
##默认长的名字在前,默认需要表assemblies_parts
#rails太强大了,可以吧assembly变成assemblies
class Assembly < ActiveRecord::Base
has_and_belongs_to_many :parts
end
class Part < ActiveRecord::Base
has_and_belongs_to_many :assemblies
#多对多的关系也可以设置很多参数
#has_and_belongs_to :assemblies, :class_name=>"Assembly", :foreigh_key=>"part_id"\
#, :association_foreign_key=>"assembly_id", :join_table=>"assemblies_parts"
end
##生成一个联合表,需要自己创建
#assemblies_parts有两个字段assembly_id和part_id
#不需要主键id和创建时间,注意修改migration文件
class CreateAssembliesPartsJoinTable < ActiveRecord::Migration
def change
create_table :assemblies_parts, id: false do |t|
t.integer :assembly_id
t.integer :part_id
end
end
end
has_many through笔记
在使用has_many through的时候,需要自己创建连接表。
假如创建的表名为user_orders,并且要写has_many :user_orders,这样才能访问到连接表
自连接
class Employe < ActiveRecord::Base
has_many :subordinate, :class_name=>"Employee", :foreign_key=> "manager_id"
belongs_to :manager, :class_name=>"Employee"
end
#迁移写法
class CreateEmployees < ActiveRecord::Migration
def change
create_table :employees do |t|
t.references :manager
t.timestamps
end
end
end
#或者t.integer :manager_id
has_one通过第三张表相连
##测试一下数据和使用方法
双向关联
#避免数据不一致的问题
class Customer < ActiveRecord::Base
has_many :orders, inverse_of: :customer
end
class Order < ActiveRecord::Base
belongs_to :customer, inverse_of: :orders
end
belongs_to关联详解
class Order < ActiveRecord::Base
belongs_to :customer, dependent: :destroy, counter_cache: true
end
#此时每个Order模型都将获得以下方法
* customer 如果关联的对象存在则返回,否则返回nil
* customer= 给关联的对象赋值
* build_customer 返回该关联类型的一个新对象,可以传值初始化,但是不会存入数据库
* create_customer 和build_customer类似,但是会存入数据库
* create_customer! 和create_customer相同,但是如果记录不合法会抛出 ActiveRecord::RecordInvalid异常
其他参数设置
:autosave 如果设置为true,保存父对象时,会自动保存所有子对象
:class_name 指定关联的模型名
:counter_cache 设置为true,提高统计所属对象数量操作的效率
:dependent选项的值有两个, :destroy 销毁对象时,也会在关联对象上调用destroy
:delete 销毁对象时,关联的对象不会调用destroy,而是会直接从数据库删除
:foreign_key 设置关联时候使用的外键
:inverse_of 不能和:polymorphic同时使用
:polymorphic 选项设置为true,多态关联
:touch 为true的时候,保存或销毁对象,关联对象的updated_at或updated_on字段会自动设置为当前时间戳,还可以指定更新哪个字段的时间touch: :orders_updated_at
:validate 设置为true,保存对象时,会同时验证关联对象
has_one关联选项
##对象获得的方法和belongs_to是一样的,下面说下参数设置
:as 表示这是多态关联
:autosave
:class_name
:dependent
:foreign_key
:inverse_of
class Supplier < ActiveRecord::Base
has_one :account, inverse_of: :supplier
end
class Account < ActiveRecord::Base
belongs_to :supplier, inverse_of: :account
end
:primary_key
:source 指定has_one :through关联的关联源名字
:source_type
:
has_many关联添加的方法
class Customer < ActiveRecord::Base
has_many :orders
end
每个 Customer模型实例都获得了这些方法:
orders(force_reload = false)
orders<<(object, ...)
orders.delete(object, ...)
orders.destroy(object, ...)
orders=objects
order_ids
order_ids=ids
orders.clear
orders.empty?
orders.size
orders.find(...)
orders.where(...)
orders.exists?(...)
orders.build(attributes = {}, ...)
orders.create(attributes = {})
orders.create!(attributes = {})
多态关联
#在同一个关联中,模型可以属于其他多个模型,
class Picture < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
end
class Employee < ActiveRecord::Base
has_many :pictures, as: :imageable
end
class Product < ActiveRecord::Base
has_many :pictures, as: :imageable
end
class CreatePictures < ActiveRecord::Migration
def change
create_table :pictures do |t|
t.string :name
t.integer :imageable_id
t.string :imageable_type
t.timestamps
end
end
end
简化写法
class CreatePictures < ActiveRecord::Migration
def change
create_table :pictures do |t|
t.string :name
t.references :imageable, polymorphic: true
t.timestamps
end
end
end
conditions的使用
has_many :children,
:class_name=> 'NurseAid::HospitalStruct',
:foreign_key => 'father_id',
:conditions => ["deep=4"]
:conditions => ["questions IS NOT NULL"]
:conditions => {:key => "exam_selector_params"}