我已在 05:15 的 Go Rails 视频中看到显示的代码: 视频教程
<%= form_with model: Link.new do |form| %>
# ...
<% end %>
通常我会写一个 new-action。类似这样的:
def new
@link = Link.new
end
显然,在调用 form_with 时,可以跳过该操作并动态创建所需的对象。
拥有 new-action 有什么好处?
是否有一条单独的路线,在调用时创建表单?
我是 Ruby on Rails 的新手,我想知道是否可以在 Rails 中创建单层路径名。
据我所知,您只能创建类似 的路线home/about
。有没有办法只创建/about
?
get '/test'
我尝试使用其自己的控制器和视图中的单个 HTML 页面来执行此操作test
,但 Rails 抛出了一个名为:ArgumentError: Missing :controller key on routes definition, please check your routes.
这是否意味着我无法创建类似 的路径/about
,但我必须创建类似 的路径home/about
?我认为之前没有人问过这个问题。
我有一个DashboardController
。这是用户查看其个人资料、设置等的页面。
对我来说,仪表板是单一的,这是有意义的。
目前,仪表板也是根。只要用户登录,用户就可以访问他们的仪表板。一个用户可以有多个children
,所以我添加了一个向控制器添加子项的操作。
我已经定义了路线,因此:
resource :dashboard, only: [:show], path: 'dashboard' do
post :create_child, on: :collection
end
resolve("Dashboard") { [:dashboard] }
root "dashboard#show"
根显示为单数,但到控制器的路径是复数,嵌套路由也是如此。
create_child_dashboard POST /dashboard/create_child(.:format) dashboards#create_child
dashboard GET /dashboard(.:format) dashboards#show
root GET / dashboard#show
我希望 URL 是单数。如何确保这一点?
我在管理 npm 包时遇到了麻烦importmap-rails
。我理想情况下希望它能像 yarn 一样运行,它可以跟踪版本、依赖项并使用类似 的命令为您下载所有内容yarn install
。
但似乎importmap-rails
只有在您固定某些内容时才会使用 cdn。这是真的吗?或者它可以使用类似 yarn 的命令下载软件包及其依赖项吗?
如果做不到这一点,我可以使用importmap-rails
yarn 作为包管理器吗?我尝试使用 underscore.js,但遇到了一些问题。
yarn add underscore
,发现它已正确下载,然后添加node_modules
到资产路径中,以便propshaft
知道importmap-rails
去那里查看:config/application.rb
config.assets.paths << Rails.root.join('node_modules')
然后固定下划线文件夹:
# config/importmap.rb
pin_all_from 'node_modules/underscore', under: 'underscore'
然后导入我需要的功能:
// from a custom js file
import debounce from 'underscore/modules/debounce';
运行./bin/importmap json
显示找到了debounce.js文件:
{
"imports": {
"application": "/assets/application-bd82d6ab.js",
"underscore/amd/_baseCreate": "/assets/underscore/amd/_baseCreate-7eccab16.js",
"underscore/amd/_baseIteratee": "/assets/underscore/amd/_baseIteratee-5f781255.js",
"underscore/amd/_cb": "/assets/underscore/amd/_cb-dd403ec6.js",
"underscore/amd/_chainResult": "/assets/underscore/amd/_chainResult-4b98e265.js",
"underscore/amd/_collectNonEnumProps": "/assets/underscore/amd/_collectNonEnumProps-ed4c206f.
...
"underscore/modules/debounce": "/assets/underscore/modules/debounce-decaec4e.js",
在浏览器中,我没有收到 debounce.js 的任何错误,它被指纹识别并被发现,但在该文件内部,它使用相对路径导入其他函数,这导致了 404 错误。此外,对 underscore 中的每个文件都发出了 get 请求,这也不好。
15:41:34 web.1 | Completed 200 OK in 5482ms (Views: 2431.0ms | ActiveRecord: 557.1ms (24 queries, 6 cached) | GC: 368.1ms)
15:41:34 web.1 |
15:41:34 web.1 |
15:41:34 web.1 | Started GET "/assets/underscore/amd/_baseCreate-7eccab16.js" for ::1 at 2024-12-20 15:41:34 -0500
15:41:35 web.1 | Started GET "/assets/underscore/amd/_baseIteratee-5f781255.js" for ::1 at 2024-12-20 15:41:35 -0500
15:41:35 web.1 | Started GET "/assets/underscore/amd/_cb-dd403ec6.js" for ::1 at 2024-12-20 15:41:35 -0500
15:41:35 web.1 | Started GET "/assets/underscore/amd/_chainResult-4b98e265.js" for ::1 at 2024-12-20 15:41:35 -0500
15:41:35 web.1 | Started GET "/assets/underscore/amd/_collectNonEnumProps-ed4c206f.js" for ::1 at 2024-12-20 15:41:35 -0500
15:41:35 web.1 | Started GET "/assets/underscore/amd/_createAssigner-aa588b74.js" for ::1 at 2024-12-20 15:41:35 -0500
15:41:36 web.1 | Started GET "/assets/underscore/amd/_createEscaper-3ea6026c.js" for ::1 at 2024-12-20 15:41:36 -0500
15:41:36 web.1 | Started GET "/assets/underscore/amd/_createPredicateIndexFinder-f577fa32.js" for ::1 at 2024-12-20 15:41:36 -0500
...
debounce-decaec4e.js:1
GET http://localhost:3000/assets/underscore/modules/restArguments.js 404 (Not Found)
debounce-decaec4e.js:2
GET http://localhost:3000/assets/underscore/modules/now.js net::ERR_ABORTED 404 (Not Found)
debounce-decaec4e.js
import restArguments from './restArguments.js';
import now from './now.js';
那么,我可以将 importmap-rails 与 yarn 一起使用,或者代替 yarn 使用 npm 包吗?
我在 Google 上搜索并梳理了文档,只有这个简短的描述: https://github.com/rails/importmap-rails/blob/main/README.md#using-npm-packages-via-javascript-cdns
为了补充背景信息,我刚刚将我们的 rails 7 应用更新到了 rails 8,所以我们刚刚从 sprockets、yarn、webpacker 换到了带有 importmap-rails 的 propshaft。很高兴没有 webpacker,但缺少了 yarn 功能。
从一个名为 Field 的模型开始,该模型包含一个名为“polygon”(笛卡尔坐标作为数组)的列,我想用 RGeo 计算公顷的面积:
class Field < ApplicationRecord
def area
factory = RGeo::Cartesian.factory(srid: 4326)
polygon = factory.polygon(self.polygon)
polygon.area
end
end
不幸的是,我总是收到这个错误信息:
NoMethodError (undefined method `factory' for #<Array:0x0000aaaac742b9a0>)
我正在使用 rgeo 3.0.0
自从将主动存储的更改移植到 pdf 文件变体的预处理中以来,它现在开始产生失败的作业。我的应用程序不需要预览。有什么方法可以禁用或关闭此行为吗?查看源代码后发现它似乎已经很好地嵌入其中,只有 monkey patching 才能绕过它。我不太热衷于 monkey patching 核心代码,因为它可能会在以后的升级中给我带来问题。
任何帮助都将不胜感激。
设置:
rails new testing --minimal
cd testing
bin/rails g model Property name handle --no-timestamps
bin/rails db:migrate
sed -i '2i \ normalizes :handle, with: ->(handle) { handle.to_s.underscore.parameterize(separator: "_") }' app/models/property.rb
# app/models/property.rb
class Property < ApplicationRecord
normalizes :handle, with: ->(handle) { handle.to_s.underscore.parameterize(separator: "_") }
end
handle
在创建/更新记录以及搜索时需要进行规范化:
Property.create(name: "My property", handle: " My property ")
#=> #<Property:0x00007f9b3a0e2e50 id: 1, name: "My property", handle: "my_property">
# ^^^^^^^^^^^
Property.where(handle: " myProperty ").to_sql
#=> "SELECT \"properties\".* FROM \"properties\" WHERE \"properties\".\"handle\" = 'my_property'"
# ^^^^^^^^^^^
但是当LIKE
使用 arel 构建查询时%
,字符也会被剥离,而这些字符应该是查询的一部分:
Property.arel_table[:handle].matches("%prop%").to_sql
#=> "\"properties\".\"handle\" LIKE 'prop'"
# ^^^^
我可以避免这样做where("handle LIKE ?")
并始终保持handle
正常化吗?
我正在更新使用 jquery 和 $ajax() 的旧 Rails 应用程序,更新后它仍然有效。我想将 ajax 调用更改为带有 .js.erb 和 params 的 fetch(),一切似乎都很好,但 html 不会被 workbar_work 部分替换。有什么建议吗?
在控制器中:
def switch_state
permitted_params = params.permit(:partial)
@partial = permitted_params[:partial].to_s
@exercise = current_exercise # defined somewhere else
respond_to do |format|
format.js
end
end
在 switch_state.js.erb 中
$('#workbar_switch').html("<%= j render(partial: @partial, :locals => {exercise: @exercise@}) %>");
获取调用
function switchState(partial, exercise){
const params = new URLSearchParams();
params.append('partial', partial);
fetch("/work/switch_state", {
method: 'POST',
headers: {
'Accept': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript',
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content,
'Content-Type': 'application/x-www-form-urlencoded'
},
body: params
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.text()
})
.then(responseText => {
console.log("received js", responseText)
})
.catch(error => {
console.log('Update failed', error)
console.log('error', error.message)
})
.finally(() => {
})
}
rails 服务器日志-看起来不错:
Started POST "/work/switch_state" for ::1 at 2024-12-07 11:19:49 +0100
Processing by WorkController#switch_state as JS
Parameters: {"partial"=>"workbar_work"}
Exercise Load (0.3ms) SELECT "exercises".* FROM "exercises" WHERE "exercises"."unit" = $1 LIMIT $2 [["unit", "ct100_1_ma3"], ["LIMIT", 1]]
↳ app/models/exercise.rb:81:in `find_exercise'
CACHE Exercise Load (0.0ms) SELECT "exercises".* FROM "exercises" WHERE "exercises"."unit" = $1 LIMIT $2 [["unit", "ct100_1_ma3"], ["LIMIT", 1]]
↳ app/models/exercise.rb:81:in `find_exercise'
Rendering work/switch_state.js.erb
Rendered work/_workbar_work.html.erb (Duration: 0.6ms | Allocations: 351)
CACHE Exercise Load (0.0ms) SELECT "exercises".* FROM "exercises" WHERE "exercises"."unit" = $1 LIMIT $2 [["unit", "ct100_1_ma3"], ["LIMIT", 1]]
↳ app/models/exercise.rb:81:in `find_exercise'
Rendered work/switch_state.js.erb (Duration: 3.4ms | Allocations: 2535)
Completed 200 OK in 17ms (Views: 5.4ms | ActiveRecord: 2.1ms | Allocations: 9998)
浏览器控制台:
[Log] response – Response {type: "basic", url: "http://localhost:3000/work/switch_state", redirected: false, …} (ctrl-dc34a42ad73de8380cf755f815535ed1b8bfc04007d2b4f4fad4a1f130e93d45.js, line 183)
[Log] received js – "$('#workbar_switch').html(\"<ul>\\n\t\\n\t<a title=\\\"Klicke hier für eine leichte Übung\\\" id=\\\"bug_click\\\" href=\\\"\\\">\\n\t<l…" (ctrl-dc34a42ad73de8380cf755f815535ed1b8bfc04007d2b4f4fad4a1f130e93d45.js, line 190)
"$('#workbar_switch').html(\"<ul>\\n \\n <a title=\\\"Klicke hier für eine leichte Übung\\\" id=\\\"bug_click\\\" href=\\\"\\\">\\n <li id=\\\"workbar_bug\\\">\\n <i class=\\\"fa fa-bug\\\"><\\/i>\\n <span id=\\\"bug_text\\\"><\\/span>\\n <\\/li>\\n<\\/a> <a title=\\\"andere Stufe\\\" id=\\\"back_to_base_click\\\" href=\\\"\\\">\\n <li id=\\\"change_level\\\">\\n <i class=\\\"fa fa-signal\\\"><\\/i>\\n <span>andere Stufe<\\/span>\\n <\\/li>\\n<\\/a> \\n<\\/ul>\\n\\n<form id=\\\"answerForm\\\"\\n name=\\\"answerForm\\\"\\n action=\\\"#dummy\\\">\\n\\n <div id= \\\"answer_field\\\"\\n title= \\\"Tippe Deine Antwort hier\\\">\\n <input type = \\\"text\\\"\\n id = \\\"txtanswer\\\"\\n name = \\\"txtanswer\\\"\\n size = \\\"3\\\"\\n maxlength = \\\"3\\\" />\\n <\\/div>\\n \\n <button type=\\\"submit\\\" \\n id=\\\"submit_answer\\\">\\n <i class=\\\"fa fa-level-down fa-rotate-90\\\"><\\/i>\\n <span>OK<\\/span>\\n <\\/button>\\n\\n<\\/form>\\n\\n\");"
我正在开发一个使用 ActiveRecord::SessionStore 进行会话管理的 Rails 应用程序。在调试时,我注意到有关 session_id 的一个有趣行为。以下是我发现的内容:
用户 cookie 中的 session_id 如下所示:
a5ef128d435c9c14f86450b0860d424
但是,在数据库(会话表)中,session_id 以哈希格式存储,并带有前缀:
2::3d05cf25eccf392f19e0049fa0f302a7bd4575a3b3daea9a2cde3173f723f7a0
我理解 2:: 后面的部分是 cookie 值 (session_id) 的 SHA-256 哈希值,但我对前缀 (2::) 很好奇:
以下是我尝试在代码中检索会话的方法:
current_user_id = lambda { |request|
session_id = request.cookie_jar["_session_id"]
return unless session_id.present?
encrypted_session_id = "2::#{Digest::SHA256.hexdigest(session_id)}"
session = ActiveRecord::SessionStore::Session.find_by(session_id: encrypted_session_id)
session&.data&.fetch('user_id', nil)
}
这按预期工作,但我有一个担心:如果前缀 2:: 发生变化,我的代码就会中断。
如能提供任何见解或对文档的指引,我们将不胜感激!
我正在尝试编辑 rails 凭证文件,就像这样。
EDITOR="subl --wait" bin/rails credentials:edit
# Editing config/credentials.yml.enc...
# File encrypted and saved.
文件在 sublime 中加载,但它立即加密并保存,没有给我机会编辑文件。这是为什么?我需要做什么才能确保我可以编辑和保存文件?
我可以确认崇高就在我的道路上:
which subl
# /usr/local/bin/subl
** 更新 **
我发现,设置编辑器没有效果。无论如何,凭据都会在 Sublime 中打开:
# Each results in credentials opening in sublime
EDITOR="subl --wait" bin/rails credentials:edit
EDITOR="nano --wait" bin/rails credentials:edit
EDITOR="vim --wait" bin/rails credentials:edit