Rails数据库

支持的数据类型

  • :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通过第三张表相连

Rails数据库_第1张图片
Paste_Image.png
##测试一下数据和使用方法

双向关联

#避免数据不一致的问题
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"}

你可能感兴趣的:(Rails数据库)