Rails has_many 和 has_one 带参数
Rails has_many and has_one with argument
我有如下设置:
user.rb
class User < ActiveRecord::Base
...
has_many :projects_users
has_many :projects, through: :projects_users
...
end
projects_users.rb
class ProjectsUser < ActiveRecord::Base
belongs_to :project
belongs_to :user
has_one :projects_users_role
end
project.rb
class Project < ActiveRecord::Base
has_many :projects_users
has_many :users, through: :projects_users
end
用户嵌套在我的路由文件中的项目下。
出于某种原因,我似乎找不到为用户访问单个项目的好方法。理想情况下,我想创建一个
has_one :project_user
协会然后
has_one :project, through: :project_user
并以某种方式将项目的 ID 传递给协会(我知道这是不可能的)。任何好的方法的想法。
然后我想调用类似于
的方法
@user = User.includes(:project (project_id parameter).find(:id)
在我的用户控制器中。
非常感谢任何帮助。
谢谢
更新
我基本上在 projects_users.rb 中为每个用户的每个项目附加了一个角色(上面更新并在下面添加)
projects_users.rb
class ProjectsUser < ActiveRecord::Base
belongs_to :project
belongs_to :user
has_one :projects_users_role
end
projects_users_role.rb
class ProjectsUsersRole < ActiveRecord::Base
belongs_to :projects_user
enum role: [...]
end
我的目标(我之前应该说明)是能够通过
之类的途径为给定项目的用户编辑此角色
/projects/1/users/2/edit-roles
这将显示用户,并允许我将角色分配给 projects_users_roles table,并添加嵌套 ID,即来自 project_users [=92= 的 ID ].因此,我希望(我认为)有一个 has_one 到带有参数的项目,这样我的嵌套形式会更简单。
更新 2
我偶然发现了这个
has_one :project_department, ->(department) { where department: department }, class_name: 'ProjectDepartment'
从这里 http://www.rojotek.com/blog/2014/05/16/cool-stuff-you-can-do-with-rails-has_one/ 但不能应用它,因为用 'project' 替换 'department' 不使用连接中的项目 ID,但在我的情况下使用用户 ID。
user.rb 更新
...
has_one :project_user, -> (project) { where project: project}, class_name: 'ProjectsUser'
has_one :project, through: :project_user
...
从控制台
User.first.project_user(1)
User Load (0.2ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1
ProjectsUser Load (0.1ms) SELECT `projects_users`.* FROM `projects_users` WHERE `projects_users`.`user_id` = 26 AND `projects_users`.`project_id` = 26 LIMIT 1
在这种情况下,project_id 应该是 1,但它使用的是 user.id 26。不知道为什么。
再次感谢
在一个 SQL 语句中产生结果的多种方法之一是使用左连接:
@user=User.joins(:projects).
where("users.id = ? and projects.id = ?",
params[:id],
params[:project_id]).take # use take to get one row only
更新
上面的语句会产生一个额外的 SQL 请求,如果你想得到:
@user.projects.first.id
如果您不想再为该项目添加语句(当然您不想),您应该将连接与包含结合起来:
@user=User.joins(:projects).includes(:projects).
where("users.id = ? and projects.id = ?",
params[:id],
params[:project_id]).take # use take to get one row only
所以现在
@user.projects.first.id
不会产生额外的 SQL 语句
这是正确的,如果你有一个模型 User
,传递给闭包的参数是被调用的 class 实例的 self
,即它将是一个实例User
。所以在下面的代码片段中 project
变量将有一个 user
值。
user.rb
has_one :project_user, -> (project) { where project: project}, class_name: 'ProjectsUser'
要将附加参数传递给 has_many/one
关系,请使用扩展选择器:
class User < ActiveRecord::Base
has_one :project_user, class_name: 'ProjectsUser' do
def for_project(project)
where(project: project)
end
end
end
customers.project_user.for_project(project)
该方法在 Rails Association
页的 Association Extension
标题中进行了描述。
我有如下设置:
user.rb
class User < ActiveRecord::Base
...
has_many :projects_users
has_many :projects, through: :projects_users
...
end
projects_users.rb
class ProjectsUser < ActiveRecord::Base
belongs_to :project
belongs_to :user
has_one :projects_users_role
end
project.rb
class Project < ActiveRecord::Base
has_many :projects_users
has_many :users, through: :projects_users
end
用户嵌套在我的路由文件中的项目下。
出于某种原因,我似乎找不到为用户访问单个项目的好方法。理想情况下,我想创建一个
has_one :project_user
协会然后
has_one :project, through: :project_user
并以某种方式将项目的 ID 传递给协会(我知道这是不可能的)。任何好的方法的想法。
然后我想调用类似于
的方法 @user = User.includes(:project (project_id parameter).find(:id)
在我的用户控制器中。
非常感谢任何帮助。
谢谢
更新
我基本上在 projects_users.rb 中为每个用户的每个项目附加了一个角色(上面更新并在下面添加)
projects_users.rb
class ProjectsUser < ActiveRecord::Base
belongs_to :project
belongs_to :user
has_one :projects_users_role
end
projects_users_role.rb
class ProjectsUsersRole < ActiveRecord::Base
belongs_to :projects_user
enum role: [...]
end
我的目标(我之前应该说明)是能够通过
之类的途径为给定项目的用户编辑此角色 /projects/1/users/2/edit-roles
这将显示用户,并允许我将角色分配给 projects_users_roles table,并添加嵌套 ID,即来自 project_users [=92= 的 ID ].因此,我希望(我认为)有一个 has_one 到带有参数的项目,这样我的嵌套形式会更简单。
更新 2
我偶然发现了这个
has_one :project_department, ->(department) { where department: department }, class_name: 'ProjectDepartment'
从这里 http://www.rojotek.com/blog/2014/05/16/cool-stuff-you-can-do-with-rails-has_one/ 但不能应用它,因为用 'project' 替换 'department' 不使用连接中的项目 ID,但在我的情况下使用用户 ID。
user.rb 更新
...
has_one :project_user, -> (project) { where project: project}, class_name: 'ProjectsUser'
has_one :project, through: :project_user
...
从控制台
User.first.project_user(1)
User Load (0.2ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1
ProjectsUser Load (0.1ms) SELECT `projects_users`.* FROM `projects_users` WHERE `projects_users`.`user_id` = 26 AND `projects_users`.`project_id` = 26 LIMIT 1
在这种情况下,project_id 应该是 1,但它使用的是 user.id 26。不知道为什么。
再次感谢
在一个 SQL 语句中产生结果的多种方法之一是使用左连接:
@user=User.joins(:projects).
where("users.id = ? and projects.id = ?",
params[:id],
params[:project_id]).take # use take to get one row only
更新
上面的语句会产生一个额外的 SQL 请求,如果你想得到:
@user.projects.first.id
如果您不想再为该项目添加语句(当然您不想),您应该将连接与包含结合起来:
@user=User.joins(:projects).includes(:projects).
where("users.id = ? and projects.id = ?",
params[:id],
params[:project_id]).take # use take to get one row only
所以现在
@user.projects.first.id
不会产生额外的 SQL 语句
这是正确的,如果你有一个模型 User
,传递给闭包的参数是被调用的 class 实例的 self
,即它将是一个实例User
。所以在下面的代码片段中 project
变量将有一个 user
值。
user.rb
has_one :project_user, -> (project) { where project: project}, class_name: 'ProjectsUser'
要将附加参数传递给 has_many/one
关系,请使用扩展选择器:
class User < ActiveRecord::Base
has_one :project_user, class_name: 'ProjectsUser' do
def for_project(project)
where(project: project)
end
end
end
customers.project_user.for_project(project)
该方法在 Rails Association
页的 Association Extension
标题中进行了描述。