[英]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
用戶嵌套在我的路線文件中的Project下。
由於某種原因,我似乎找不到為用戶訪問單個項目的好方法。 理想情況下,我想創建一個
has_one :project_user
關聯,然后
has_one :project, through: :project_user
並以某種方式將項目的ID和ID傳遞給關聯(我知道這是不可能的)。 任何好的方法的想法。
然后,我想調用類似於
@user = User.includes(:project (project_id parameter).find(:id)
在我的用戶控制器中。
非常感謝您的協助。
謝謝
UPDATE
我本質上是在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表,並添加嵌套的ID,即project_users表中的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/,但是不能以將“部門”替換為“項目”來應用在聯接中不使用項目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.id26。不確定為什么。
再次感謝
沒錯,如果您有模型User
,則傳遞給閉包的參數是被調用類實例的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
頭中進行了描述。
在一個SQL語句中產生結果的多種方法之一是左連接:
@user=User.joins(:projects).
where("users.id = ? and projects.id = ?",
params[:id],
params[:project_id]).take # use take to get one row only
UPDATE
如果您希望獲得上述聲明,則會產生一個額外的SQL請求:
@user.projects.first.id
如果您不希望該項目有更多的語句(當然,您不希望這樣做),則應將join和include結合使用:
@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語句
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.