我有一个模型下载
,带有一个表下载
。 downloads
有一个名为 ip_address
的字段,它将 ip 地址存储为整数。我想设置一个 IpAddress
模型,但没有 ip_addresses 表,所以我可以做类似的事情
Download.find(1).ip_address.to_s # '127.0.0.1'
Download.find(1).ip_address.to_i # 2130706433
Download.find(1).ip_address.downloads # SELECT * FROM downloads WHERE ip_address='2130706433'
IpAddress.find(2130706433).downloads # SELECT * FROM downloads WHERE ip_address='2130706433'
我希望它表现得像:
class Download < ActiveRecord::Base
belongs_to :ip_address, :foreign_key => :ip_address
end
class IpAddress < ActiveRecord::Base
set_primary_key :ip_address
has_many :downloads, :foreign_key => :ip_address
end
但没有无用的 ip 地址表。
这可能吗?
编辑
我发现ruby已经有了一个IPAddr class .
所以我这样做了:
require 'ipaddr'
class Download < ActiveRecord::Base
attr_accessible :ip, ...
def ip
@ip ||= IPAddr.new(read_attribute(:ip), Socket::AF_INET)
end
def ip=(addr)
@ip = IPAddr.new(addr, Socket::AF_INET)
write_attribute(:ip, @ip.to_i)
end
def self.for_ip(addr)
where(:ip => IPAddr.new(addr, Socket::AF_INET).to_i)
end
end
然后我可以做很多很酷的事情
Download.new(:ip => '127.0.0.1').save
Download.for_ip('127.0.0.1').first.ip.to_i # 2130706433
最佳答案
belongs_to
实际上是为了指定两个表中对象之间的关联。但你是对的,除非你需要存储其他相关数据,否则将 IP 地址存储在表中是毫无用处的。
但是,您可以使用 scopes去完成你想要的。你可以在你的下载模型中有这样的东西:
class Download < ActiveRecord::Base
scope :for_ip, lambda { |x| where(:ip_address => x) }
end
然后你会打电话
Download.for_ip(2130706433)
获取该 IP 的下载列表。
你也可以添加一个类方法:
class Download < ActiveRecord::Base
def self.for_ip(x)
where(:ip_address => x)
end
end
如果您想从字符串转换为数字 IP 地址,这可能会很方便。
而且,如果您想要一个 IPAddress 类,您可以添加如下方法:
class IPAddress
def initialize(ip)
#presumably do some stuff here
@ip = ip
end
def downloads
Download.for_ip(@ip)
end
end
关于ruby-on-rails - belongs_to 没有额外表的关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11903989/