【问题标题】:Getting values through relational table通过关系表获取值
【发布时间】:2013-02-14 12:51:56
【问题描述】:

在我的应用程序中,我有一个页面可以呈现数据库中的所有项目。我想要的是能够过滤结果,例如只显示用户是成员的一次。

以下来自我的项目控制器,我想在其中执行此操作(仅显示用户是成员的项目)。要做的是首先从找到 user_id 的“ProjectUser”中获取所有项目。然后我想使用这个数组从表“项目”中检索所有相关项目,并使用@user_is_member.project_id。

这不起作用,因为它只给我一个项目,而不是全部。

如何更改代码以完成我想要的?

代码:

@user_is_member = ProjectsUser.where(:user_id => current_user.id)

@user_is_member.each do |member|
    @projects = Project.where(:id => member.project_id)
end

表格:

projects_users:

project_id
user_id

项目:

id
...non relevant fields...

型号:

用户模型:

class User < ActiveRecord::Base
  has_many :project_users
  has_and_belongs_to_many :projects
end

项目模型:

class Project < ActiveRecord::Base
  has_and_belongs_to_many :users # => , :class_name => 'User'

  belongs_to :user
end

ProjectUser 模型:

class ProjectsUser < ActiveRecord::Base
  belongs_to :user
  belongs_to :project
end

注意: current_user 是当前登录的用户(可以访问所有用户字段,例如“id”)

【问题讨论】:

  • current_user 是什么?是登录用户吗?
  • @gabrielhilal:是的。
  • 您的模型中是否设置了关联?如果您可以在此处添加模型代码,那就太好了。在您当前的情况下,您可以创建一个项目 ID 数组,projects = []@user_is_member.each {|p| projects &lt;&lt; p.project_id} 然后 @projects = Project.where(:id =&gt; projects)。但如果你有正确的联想,那么你不应该走这条路。
  • 您的用户模型中存在不明确的关联。
  • @SybariteManoj 是对的...另外,projectuser 属于用户,但用户没有定义 has_many projectusers...

标签: ruby-on-rails database ruby-on-rails-3 relational-database


【解决方案1】:

这不是关联模型的好方法。如果您想将用户关联到项目并将一个用户设置为管理员/创建者,那么您应该将您的模型关联为:

用户

class User < ActiveRecord::Base
 attr_accessible :first_name, :last_name, :email, :password
 has_secure_password

 has_many :projects_users
 has_many :projects, :through => :projects_users
end

项目

class Project < ActiveRecord::Base
 has_many :projects_users
 has_many :users, :through => :projects_users
end

项目用户

class ProjectsUser < ActiveRecord::Base
 attr_accessible :role

 belongs_to :user
 belongs_to :project
end

我已向您的 ProjectsUser 模型添加了一个额外的列/属性,该模型将具有一个字符串值(管理员/成员)。现在您可以通过@project.users.where(:role =&gt; 'member') 和通过@project.users.where(:role =&gt; 'admin').first 管理来获得项目的成员。

如果您不想改变自己的方式,那么在您的控制器中执行以下操作:

@user_is_member = ProjectsUser.where(:user_id => current_user.id)
project_ids = []

@user_is_member.each do |member|
  project_ids << member.project_id
end

@projects = Project.where(:id => project_ids)

【讨论】:

  • 这就是我所说的+1
【解决方案2】:

如果你想要current_user 的所有项目,你可以这样做:

  @projects = current_user.projects

我假设你有类似的东西:

class User < ActiveRecord::Base
  has_many :project_users
  has_many :projects, :through => :project_users
end

class ProjectUser < ActiveRecord::Base
  belongs_to :user
  belongs_to :project
end

class Project < ActiveRecord::Base
  has_many :project_users
  has_many :users, :through => :project_users
end

【讨论】:

  • 这给了我用户是管理员的项目,在这种情况下这不是我想要的。 ://
  • 好的,它的工作原理是这样的:在项目表中有一个名为 user_id 的字段,其中包含项目的创建者(管理员)。然而,项目成员存储在 projects_users 中(通过 -> user_id、project_id)。在这种情况下,我只想要当前用户所属的项目,即通过 projects_users 选项卡。
  • 但是用户不应该拥有“has_and_belongs_to: projects”,因为用户可以是许多项目的管理员吗?
  • 尝试了您的关联建议,并使用“@projects = current_user.projects”访问项目。但是,出现错误:“未初始化的常量 User::ProjectUser”
  • throughhas_and_belongs_to: projects 好得多...看看@SybariteManoj 的答案。
【解决方案3】:

问题是您没有project_id 用于某些以某种方式被删除的用户。

通过将puts 类似语句放入循环中,检查您的数据库project_idnil

或者,您可以在您的关系上使用:dependent =&gt; :destroy 来消除这种不一致的数据。它通常发生在您测试并以某种方式删除任何记录但忘记删除其他表的外键关联关系时。

这可以通过以下方式完成:

@user_is_member = ProjectsUser.where(:user_id => current_user.id)

@user_is_member.each do |member|

puts "Checking the project id existence for each user member"+member.project_id.to_s

end

【讨论】:

  • @user_is_member 是一个数组。所以没有与之关联的project_id
  • 是的,您必须在此循环中进行迭代,并且对于此数组的每个用户,您必须检查关联的项目。我怀疑没有与任何用户成员关联的项目,因此出现未定义的错误。
猜你喜欢
  • 2014-12-28
  • 1970-01-01
  • 1970-01-01
  • 2018-11-27
  • 2016-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-05
相关资源
最近更新 更多