我有一个使用activerecord的本地用户模型。用户有一个电子邮件字段。我还有一个名为tasks的activeresource模型,它有一个created_by字段,用于存储提交用户的电子邮件地址。我想将这两者联系起来,但我正在努力使用正确的语法,甚至是否可能。
ActiveResource的主要分支似乎甚至不支持外键。我找到了alternative branch,但仍然无法正常工作。
class User < ActiveRecord::Base
has_many :tasks
end
class Task < ActiveResource::Base
belongs_to :user
schema do
string 'created_by' #email
# other fields
end
end
答案 0 :(得分:4)
您的代码应该可以正常工作,因为user_id
上有Task
属性作为外键,或者您可以在User
模型上的关联中指定外键如下:
class User < ActiveRecord::Base
has_many :tasks, foreign_key: "uid"
end
现在问题是,您无法在belongs_to
上使用ActiveResource
,所以除非您需要从user
类的实例中检索Task
,你可以删除它,关系的另一面仍然可以工作,但是,如果你需要检索user
,那么你必须按如下方式实现自己的finder方法:
class Task < ActiveResource::Base
schema do
string 'created_by' #email
# other fields
end
def user
@user ||= User.find self.user_id # use the attribute name that represents the foreign key
end
def user=(user)
@user = user
self.update_attribute(:user_id, user.id)
end
end
这基本上与您在ActiveRecord
模型上的预期相同,但如果您有多个关联,这可能会很烦人,因此您可以扩展ActiveResource
模块以添加{{1}如下:
belongs_to
这将允许您在任何module BelongsToActiveResource
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def belongs_to( name, options = {} )
class_eval %(
def #{name}
@#{name} ||= name.to_s.classify.find( name.id )
end
def #{name}=(obj)
@#{name} ||= obj
self.update_attribute((name.to_s + "_id").to_sym, @#{name}.id
end
)
end
end
end
ActiveResource::Base.class_eval { include BelongsToActiveResource }
模型上使用belongs_to。
P.S。:上述解决方案的灵感来自https://stackoverflow.com/a/8844932/3770684
答案 1 :(得分:1)
你不能,但你可以通过自己实施访问者方法来伪造它。
class User < ActiveRecord::Base
#has_many :tasks
def tasks
Task.find(:all, params: {created_by: email})
end
end
class Task < ActiveResource::Base
#belongs_to :user
def user
User.where(email: created_by).first
end
schema do
string 'created_by' #email
# other fields
end
end
这将允许您编写代码,就像您的对象相关联(即User.first.tasks.length
)。但是,他们并没有真正加入。这意味着调用User.first.tasks
将打到数据库,然后发出额外的HTTP请求来检索任务。根据代码的结构,您可能会遇到意外的性能问题。
此外,您无法运行单个查询来获取用户和所有关联的任务(因为它是两个独立的数据存储),您无法执行此操作做像User.joins(:tasks).where({tasks: field_1: true})
这样的花哨的东西。