Rails 4 - 将地址保存为数据库中的一列
Rails 4 - Save address as one column in database
我是 rails 的新手,正在开发一个简单的应用程序。我的 ERD 中有一个名为 Client 的模型,我想为每个客户保存地址。
我最初的想法是将地址保存为单独的字段,即:
rails g model Client address_first:string address_second:string city:string ...
但这看起来效率很低。我确定必须有一种方法可以将地址保存为散列、数组或者 JSON?我四处阅读,人们一直提到使用 "serialise",但我不确定是否以及如何为地址字段实现它。
如有任何帮助,我们将不胜感激。
谢谢
Rails 正在帮助 oyu
class Client
serialize :address
end
http://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html
http://api.rubyonrails.org/classes/ActiveModel/Serialization.html
这取决于您使用的数据库 - MySQL 和 Postgres 都有 JSON 列类型 - Postgres 也有一个称为 hstore 的哈希类型。
它们在 hash/json 列中也有不同的查询选项。虽然这些数据类型非常适合动态数据,但并没有真正的性能提升(实际上可能更慢)。
而且您不能对存储在 hstore/json 列中的属性使用所有 rails 对象映射、验证等优点。
当谈到地址时,每个人都天真地把它放在用户(或客户或客户)模型中,结果发现在现实世界中您需要多个地址。
# == Schema Information
#
# Table name: clients
#
# id :integer not null, primary key
# created_at :datetime not null
# updated_at :datetime not null
#
class Client < ActiveRecord::Base
has_many :addresses
end
# == Schema Information
#
# Table name: addresses
#
# id :integer not null, primary key
# address_first :string
# address_second :string
# street :string
# city :string
# country :string
# client_id :integer
# created_at :datetime not null
# updated_at :datetime not null
#
class Address < ActiveRecord::Base
belongs_to :client
end
为了进一步 Max's
建议,我想补充一点,如果需要,您 可以 在单个模型中包含地址信息。
拥有多个模型很酷,但是如果您确定您只想要 Client
的某些属性,您可以努力将选项的散列保存到那里有一个专栏。
SQL
要直接回答您的问题,并详细说明 Max 的建议,有 几种您可以使用的列类型,具体取决于您 SQL 的变体雇用。
PostgreSQL (Heroku uses this) has the hstore
和 json
列类型。
这两个都为您提供了一个列,允许您存储单个序列化对象,允许您用序列化数据填充该对象:
我以前从未在 PGSQL
上使用过此功能,所以你最好 reading this blog post on how to choose between HSTORE
and JSON
column types。
--
MYSQL, which most people use, also has the capacity to store JSON:
As of MySQL 5.7.8, MySQL supports a native JSON data type that enables
efficient access to data in JSON (JavaScript Object Notation)
documents. The JSON data type provides these advantages over storing
JSON-format strings in a string column:
这似乎与它的 PGSQL 兄弟的工作方式相同。
如果您选择其中之一(您可以使用以下设置):
#clients
#id | name | email | address (json) | created_at | updated_at
...它将使您能够将 JSON 格式化的对象插入 address
列。
现在,正如 Max
所指出的,这将阻止您在 address
列上使用 运行 validations
和其他属性级逻辑。它将阻止您通过 ActiveRecord 查找此列,并且将很难以任何其他方式使用此数据,而不仅仅是存储它。
因此,如果您完全确定要以这种方式存储它,则可以 use the following to do it:
#app/models/client.rb
class Client < ActiveRecord::Base
serialize :address
end
#app/controllers/clients_controller.rb
class ClientsController < ApplicationController
def new
@client = Client.new
end
def create
@client = Client.new client_params
@client.save
end
private
def client_params
params.require(:client).permit(:name, :email, address:{})
end
end
#app/views/clients/new.html.erb
<%= form_for @client do |f| %>
<%= f.text_field :name %>
<%= f.email_field :email %>
<%= f.fields_for :address, OpenStruct.new(f.object.address || {}) do |address| %>
<%= address.text_field :street %>
<%= address.text_field :other_data %>
<% end %>
<%= f.submit %>
<% end %>
fields_for
可在此处获取:How to edit a Rails serialized field in a form?
型号
正如 Max 所指出的,替代方法是使用多个模型。
这个虽然看起来不错,其实是一个非常精细的工艺。许多人开始为所有内容插入模型,很快您的应用程序就会充满不执行任何操作的模型。
如果您想使用模型,最好使用以下内容:
#app/models/client.rb
class Client < ActiveRecord::Base
#columns id | name | email | etc | created_at | updated_at
has_one :address
before_create :build_address, unless: Proc.new { |client| client.address }
end
#app/models/address.rb
class Address < ActiveRecord::Base
#columns id | client_id | your | address | columns | here | created_at | updated_at
belongs_to :client
end
如果如果您希望地址在应用程序中发挥重要作用(IE,如果他们要运送到它等),我只会推荐这个。
如果您以任何其他不重要的形式使用该地址,我会将其保留为序列化哈希。
我是 rails 的新手,正在开发一个简单的应用程序。我的 ERD 中有一个名为 Client 的模型,我想为每个客户保存地址。
我最初的想法是将地址保存为单独的字段,即:
rails g model Client address_first:string address_second:string city:string ...
但这看起来效率很低。我确定必须有一种方法可以将地址保存为散列、数组或者 JSON?我四处阅读,人们一直提到使用 "serialise",但我不确定是否以及如何为地址字段实现它。
如有任何帮助,我们将不胜感激。
谢谢
Rails 正在帮助 oyu
class Client
serialize :address
end
http://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html
http://api.rubyonrails.org/classes/ActiveModel/Serialization.html
这取决于您使用的数据库 - MySQL 和 Postgres 都有 JSON 列类型 - Postgres 也有一个称为 hstore 的哈希类型。
它们在 hash/json 列中也有不同的查询选项。虽然这些数据类型非常适合动态数据,但并没有真正的性能提升(实际上可能更慢)。
而且您不能对存储在 hstore/json 列中的属性使用所有 rails 对象映射、验证等优点。
当谈到地址时,每个人都天真地把它放在用户(或客户或客户)模型中,结果发现在现实世界中您需要多个地址。
# == Schema Information
#
# Table name: clients
#
# id :integer not null, primary key
# created_at :datetime not null
# updated_at :datetime not null
#
class Client < ActiveRecord::Base
has_many :addresses
end
# == Schema Information
#
# Table name: addresses
#
# id :integer not null, primary key
# address_first :string
# address_second :string
# street :string
# city :string
# country :string
# client_id :integer
# created_at :datetime not null
# updated_at :datetime not null
#
class Address < ActiveRecord::Base
belongs_to :client
end
为了进一步 Max's
建议,我想补充一点,如果需要,您 可以 在单个模型中包含地址信息。
拥有多个模型很酷,但是如果您确定您只想要 Client
的某些属性,您可以努力将选项的散列保存到那里有一个专栏。
SQL
要直接回答您的问题,并详细说明 Max 的建议,有 几种您可以使用的列类型,具体取决于您 SQL 的变体雇用。
PostgreSQL (Heroku uses this) has the hstore
和 json
列类型。
这两个都为您提供了一个列,允许您存储单个序列化对象,允许您用序列化数据填充该对象:
我以前从未在 PGSQL
上使用过此功能,所以你最好 reading this blog post on how to choose between HSTORE
and JSON
column types。
--
MYSQL, which most people use, also has the capacity to store JSON:
As of MySQL 5.7.8, MySQL supports a native JSON data type that enables efficient access to data in JSON (JavaScript Object Notation) documents. The JSON data type provides these advantages over storing JSON-format strings in a string column:
这似乎与它的 PGSQL 兄弟的工作方式相同。
如果您选择其中之一(您可以使用以下设置):
#clients
#id | name | email | address (json) | created_at | updated_at
...它将使您能够将 JSON 格式化的对象插入 address
列。
现在,正如 Max
所指出的,这将阻止您在 address
列上使用 运行 validations
和其他属性级逻辑。它将阻止您通过 ActiveRecord 查找此列,并且将很难以任何其他方式使用此数据,而不仅仅是存储它。
因此,如果您完全确定要以这种方式存储它,则可以 use the following to do it:
#app/models/client.rb
class Client < ActiveRecord::Base
serialize :address
end
#app/controllers/clients_controller.rb
class ClientsController < ApplicationController
def new
@client = Client.new
end
def create
@client = Client.new client_params
@client.save
end
private
def client_params
params.require(:client).permit(:name, :email, address:{})
end
end
#app/views/clients/new.html.erb
<%= form_for @client do |f| %>
<%= f.text_field :name %>
<%= f.email_field :email %>
<%= f.fields_for :address, OpenStruct.new(f.object.address || {}) do |address| %>
<%= address.text_field :street %>
<%= address.text_field :other_data %>
<% end %>
<%= f.submit %>
<% end %>
fields_for
可在此处获取:How to edit a Rails serialized field in a form?
型号
正如 Max 所指出的,替代方法是使用多个模型。
这个虽然看起来不错,其实是一个非常精细的工艺。许多人开始为所有内容插入模型,很快您的应用程序就会充满不执行任何操作的模型。
如果您想使用模型,最好使用以下内容:
#app/models/client.rb
class Client < ActiveRecord::Base
#columns id | name | email | etc | created_at | updated_at
has_one :address
before_create :build_address, unless: Proc.new { |client| client.address }
end
#app/models/address.rb
class Address < ActiveRecord::Base
#columns id | client_id | your | address | columns | here | created_at | updated_at
belongs_to :client
end
如果如果您希望地址在应用程序中发挥重要作用(IE,如果他们要运送到它等),我只会推荐这个。
如果您以任何其他不重要的形式使用该地址,我会将其保留为序列化哈希。