有很多通过关系

时间:2014-11-14 02:20:25

标签: ruby-on-rails

在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字段?

谢谢!

3 个答案:

答案 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有示例代码。