2012 年 8 月 8 日更新
我已经缩小了问题的范围......
这条线有效
ActiveRecord::Base.connection.schema_search_path = ["11", "public"].join(",")
但这条线没有
ActiveRecord::Base.connection.schema_search_path = [workspace.id.to_s, "public"].join(",")
即使 workspace.id == 11
需要明确的是,“workspace.id”不会为循环的每次迭代更新。请注意,这只适用于 ActiveRecord::Base.connection.schema_search_path 命令
有任何想法吗?
原帖
为冗长的帖子道歉,但我真的被困住了。
背景
我正在使用 PostGreSQL 在 Rails 上开发一个多租户应用程序。租户通过 PG 模式分隔。我有一个由租户拥有的“工作区”的概念,并且在“公共”模式中有关联的记录。
每个单独的模式(工作区)都有一个“项目”表。
在每一页上,我想显示当前用户可以访问的工作区和项目的下拉列表。下拉列表的简化版本如下所示:
Workspace 1
- Project 1a
- Project 1b
Workspace 2
- Project 2a
- Project 2b
- Project 2c
...
...
Workspace 8
Project 8a
我在 lib/PgTools.rb 中有以下方法
def self.current_search_path
ActiveRecord::Base.connection.select_value "SHOW search_path"
end
def self.set_search_path(name, include_public = true)
path_parts = [name.to_s, ("public" if include_public)].compact
ActiveRecord::Base.connection.schema_search_path = path_parts.join(",")
end
从 rails 控制台使用时,这些方法似乎可以正常工作。
问题
我在 application_helper.rb 中编写了一个辅助方法来创建下拉列表。我认为这是一个放置它的好地方,因为它必须显示在每一页上。在这个辅助方法中,我必须设置 PG 搜索路径(使用 PgTools.set_search_path),以便仅迭代来自适当工作区的项目。但是搜索路径似乎没有正确设置。
相关代码如下
current_user.workspaces.each do |workspace|
html << '<li>' + workspace.name + "</li>"
PgTools.set_search_path(workspace.id) unless Rails.env.test?
html << '<li>Current search_path is ' + PgTools.current_search_path + '</li>' <!-- DEBUG LINE
Project.all.each do |project|
html << "<li>"
html << (link_to '- ' + project.name, edit_project_path(project.id))
html << "</li>"
end
end
当我查看输出时,我得到以下信息:
Workspace 1
Setting search_path to 10
Current search_path is 10, public
- Project 1a
Workspace 2
Setting search_path to 15
Current search_path is 10, public
- Project 1a
Workspace 3
Setting search_path to 14
Current search_path is 10, public
- Project 1a
如您所见,搜索路径永远不会改变,我也不知道为什么。模块方法显然是可访问的,因为“current_search_path”方法工作正常。
当我跟踪 log/development.log 时,我得到以下输出:
Workspace Load (0.6ms) SELECT "workspaces".* FROM "workspaces" INNER JOIN "workspace_memberships" ON "workspaces"."id" = wworkspace_memberships"."workspace_id" WHERE "workspace_memberships"."user_id" = 2 ORDER BY workspaces.name ASC
(0.1ms) SHOW search_path
CACHE (0.0ms) SELECT "projects".* FROM "projects"
CACHE (0.0ms) SHOW search_path
CACHE (0.0ms) SELECT "projects".* FROM "projects"
CACHE (0.0ms) SHOW search_path
CACHE (0.0ms) SELECT "projects".* FROM "projects"
CACHE (0.0ms) SHOW search_path
CACHE (0.0ms) SELECT "projects".* FROM "projects"
CACHE (0.0ms) SHOW search_path
CACHE (0.0ms) SELECT "projects".* FROM "projects"
CACHE (0.0ms) SHOW search_path
CACHE (0.0ms) SELECT "projects".* FROM "projects"
CACHE (0.0ms) SHOW search_path
CACHE (0.0ms) SELECT "projects".* FROM "projects"
CACHE (0.0ms) SHOW search_path
CACHE (0.0ms) SELECT "projects".* FROM "projects"
CACHE (0.0ms) SHOW search_path
这可能表明存在缓存问题,但我真的在这里盲目飞行,并且不喜欢禁用缓存的想法,因为我不知道可能产生的其他影响。
任何想法都非常受欢迎。我也愿意接受有关我以完全错误的方式来实现最终结果的建议。
干杯,
凯尔。