在Ruby on Rails中有很多关于构建Has_Many关系的引用,但关于如何处理这种关系的信息非常少。
我有一个包含以下变量的Users表:
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
然后我有一张维基表:
t.string "title"
t.datetime "published_at"
t.datetime "created_at"
t.datetime "updated_at"
t.text "body"
而且,我有一个Relationships表来加入这两个:
t.integer "wiki_id"
t.integer "user_id"
t.boolean "creator_created"
t.boolean "collaborator"
关系类属于其他每个类:
belongs_to :users
belongs_to :wikis
其他两个人有has_many,通过代码:
class User < ActiveRecord::Base
has_many :relationships
has_many :wikis, through: :relationships
反之亦然。
所以我的问题是,现在是什么?我怎样才能调用这些不同的类及其变量? user.wiki似乎不起作用,或者user.relationship.wiki;甚至relationship.created_creator拉错误信息!
特别是,我希望能够找出用户是否创建了一个wiki,以便该用户可以编辑该Wiki。我试图在用户模型中为此创建一个方法:
def creator?(wiki, user)
Relationship.where(wiki_id: wiki.id, user_id:user.id).creator_created
end
当我从策略文件中调用它时,我收到错误:
undefined method `creator_created' for # <ActiveRecord::Relation::ActiveRecord_Relation_Relationship:0xbb19b84>
任何人都可以通过关系帮助我使用has_many吗?如何引用与用户相关的Wiki或与两者相关的creator_created字段?
谢谢!
答案 0 :(得分:2)
has_many
关系返回一个集合。 Rails使用复数形式的关联名称来访问相关对象。
要获得用户的wiki,请执行以下操作:
user.wikis
要查找用户是否创建了Wiki,您需要使用关系:
user.wikis.where(relationships: {creator_created: true})
这显示了如何将范围链接到关联。
通过向Wiki
模型添加范围可以进一步简化:
scope :creator_created, -> { where(relationships: {creator_created: true}) }
允许:
user.wikis.creator_created
将.to_sql
添加到表达式的末尾以查看生成的SQL语句会非常有用。
Rails指南Active Record Query Interface
中涵盖了大部分内容修改强>
错误消息&#34; NameError:未初始化的常量User :: Wikis&#34;由于Relationship
模型中的错误而发生。 belongs_to
个关联使用单数形式指定相关模型,因此将它们更改为:
belongs_to :user
belongs_to :wiki
答案 1 :(得分:0)
尝试:
Relationship.where(wiki_id: wiki.id, user_id:user.id, creator_created: true)
答案 2 :(得分:0)
.where(...)
会返回模型对象的集合。
def creator?(wiki, user)
# Raises error, as a model instance method (creator_created) is
# called on a collection:
Relationship.where(wiki_id: wiki.id, user_id:user.id).creator_created
end
在上面的代码中,我们尝试在.creator_created
个对象的集合上调用Relationship
(假设找到符合{{1}条件的对象}})。
.where(...)
是单个 .creator_created
对象的方法。无法在Relationship
s。
修改给定的Relationship
方法以将此考虑在内会产生:
creator?
但是,鉴于该方法的名称,我怀疑这可能是一个更具可读性的解决方案:
def creator?(wiki, user)
relationships = Relationship.where(wiki_id: wiki.id, user_id: user.id)
if relationships.empty?
raise "No matching relationships found for wiki: '#{wiki}'"
end
# Use the first element from the relationships collection
relationship = relationships[0]
relationship.creator_created
end
将def creator?(wiki, user)
user.relationships.find_by(wiki_id: wiki.id).creator_created
end
与.find_by(...)
进行比较。 .where(...)
仅返回单个模型实例(如果找到匹配项)。 .find_by
docs和.where
docs有示例代码。