Sim*_*mmo 5 activerecord ruby-on-rails foreign-keys activeresource foreign-key-relationship
我有一个使用activerecord的本地用户模型.用户有一个电子邮件字段.我还有一个名为tasks的activeresource模型,它有一个created_by字段,用于存储提交用户的电子邮件地址.我想将这两者联系起来,但我正在努力使用正确的语法,甚至是否可能.
ActiveResource的主要分支似乎甚至不支持外键.我找到了另一个分支,但仍然无法正常工作.
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
Run Code Online (Sandbox Code Playgroud)
小智 5
假设您user_id在上具有Task充当外键的属性,那么您的代码应该可以正常工作,或者您可以在User模型的关联中指定外键,如下所示:
class User < ActiveRecord::Base
has_many :tasks, foreign_key: "uid"
end
Run Code Online (Sandbox Code Playgroud)
现在的问题是,你没有可以使用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
Run Code Online (Sandbox Code Playgroud)
这基本上与您在ActiveRecord模型上预期的行为相同,但是如果您具有多个关联,则可能会很累,因此您可以扩展ActiveResource模块以使其添加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 }
Run Code Online (Sandbox Code Playgroud)
这将允许您在任何ActiveResource模型上使用belongs_to 。
PS:以上解决方案的灵感来自/sf/answers/619145271/
你不能,但你可以通过自己实现访问器方法来伪造它。
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
Run Code Online (Sandbox Code Playgroud)
这将使您可以编写代码,就像您的对象是关联的一样(即User.first.tasks.length)。然而,他们实际上并没有加入。这意味着调用User.first.tasks将访问数据库,然后发出额外的 HTTP 请求来检索任务。根据代码的结构,您可能会遇到意外的性能问题。
此外,您无法运行单个查询来获取用户和所有关联的任务(因为它是两个独立的数据存储),并且您无法执行诸如User.joins(:tasks).where({tasks: field_1: true}).
| 归档时间: |
|
| 查看次数: |
1882 次 |
| 最近记录: |