在 rails 模型函数中查询另一个模型
querying another model in a rails model function
基本上,我想做的是加入文本字段而不是像
这样的 ID
SELECT country.delivery_time
FROM order, country
WHERE order.country = country.name
到目前为止我的 Rails 模型是
class Country < ApplicationRecord
validates :name, presence: true
validates :delivery_time, presence: true
end
class Order < ApplicationRecord
validates :country, presence: true
def shipping_time
# want to get the correct country from the DB
if self.country == country.name
country.delivery_time
else
"unavailable"
end
end
end
其中 shipping_time
是应该 return 连接结果的函数。我得到的错误是
undefined method `country'
我正在使用 Ruby 3.0.3 和 Rails 7.0.0。
所以我最终使用 joins
函数来获得我想要的东西,
Order.joins("INNER JOIN countries ON orders.country = countries.name")
完整功能在哪里
def shipping_time
relation = Order.joins("INNER JOIN countries ON orders.country = countries.name")
if 1 == relation.count()
relation[0].delivery_time
else
"unavailable"
end
end
打破常规并使用任何类型的外键列实际上非常简单:
class AddCountryNameToOrders < ActiveRecord::Migration[7.0]
def change
add_column :orders, :country_name, :string
# Some DB's may not allow foreign key constraints
# on non PK columns
add_foreign_key :orders, :countries,
column: :country_name,
primary_key: :name
end
end
class Order < ApplicationRecord
validates :country, presence: true
belongs_to :country,
foreign_key: :country_name,
primary_key: :name
end
class Country < ApplicationRecord
has_many :orders,
foreign_key: :country_name,
primary_key: :name
end
用作primary_key
选项的列实际上不必是目标table的PK。简单地命名列 country
会导致名称冲突,除非您为关联选择不同的名称(并使它变得更加混乱)。
但是考虑到域,这是一个非常糟糕的主意。
国家确实会更改名称 - 最近的例子是北马其顿和埃斯瓦蒂尼。
而是使用普通的 integer/uuid 外键列并使用委托从国家/地区获取名称。
class Order < ApplicationRecord
belongs_to :country
delegate :name, to: :country,
prefix: true
end
如果您想为 table 使用“自然”主键而不是代理键(例如自动生成的 ID),那么 ISO 3166 国家/地区代码是更好的选择。
基本上,我想做的是加入文本字段而不是像
这样的 IDSELECT country.delivery_time
FROM order, country
WHERE order.country = country.name
到目前为止我的 Rails 模型是
class Country < ApplicationRecord
validates :name, presence: true
validates :delivery_time, presence: true
end
class Order < ApplicationRecord
validates :country, presence: true
def shipping_time
# want to get the correct country from the DB
if self.country == country.name
country.delivery_time
else
"unavailable"
end
end
end
其中 shipping_time
是应该 return 连接结果的函数。我得到的错误是
undefined method `country'
我正在使用 Ruby 3.0.3 和 Rails 7.0.0。
所以我最终使用 joins
函数来获得我想要的东西,
Order.joins("INNER JOIN countries ON orders.country = countries.name")
完整功能在哪里
def shipping_time
relation = Order.joins("INNER JOIN countries ON orders.country = countries.name")
if 1 == relation.count()
relation[0].delivery_time
else
"unavailable"
end
end
打破常规并使用任何类型的外键列实际上非常简单:
class AddCountryNameToOrders < ActiveRecord::Migration[7.0]
def change
add_column :orders, :country_name, :string
# Some DB's may not allow foreign key constraints
# on non PK columns
add_foreign_key :orders, :countries,
column: :country_name,
primary_key: :name
end
end
class Order < ApplicationRecord
validates :country, presence: true
belongs_to :country,
foreign_key: :country_name,
primary_key: :name
end
class Country < ApplicationRecord
has_many :orders,
foreign_key: :country_name,
primary_key: :name
end
用作primary_key
选项的列实际上不必是目标table的PK。简单地命名列 country
会导致名称冲突,除非您为关联选择不同的名称(并使它变得更加混乱)。
但是考虑到域,这是一个非常糟糕的主意。
国家确实会更改名称 - 最近的例子是北马其顿和埃斯瓦蒂尼。
而是使用普通的 integer/uuid 外键列并使用委托从国家/地区获取名称。
class Order < ApplicationRecord
belongs_to :country
delegate :name, to: :country,
prefix: true
end
如果您想为 table 使用“自然”主键而不是代理键(例如自动生成的 ID),那么 ISO 3166 国家/地区代码是更好的选择。