是否可以将服务器端 ruby 嵌入到 Opal .js.rb 文件中?换句话说,我需要访问例如User.find(1)
Rails 中的一些蛋白石文件,就像使用 .erb 一样。
2 回答
听起来您正在寻找一种在初始请求中将数据传递给客户端的方法。如果您在服务器应用程序中加载数据并且只想传递它,您可以查看gon
gem。
TL;DR 版本
这足以让你的脚湿透
# Gemfile
gem 'gon'
# app/controllers/my_controller.rb
class MyController < ApplicationController
before_action { gon.push current_user: User.find(session[:user_id]) }
end
# app/views/layouts/application.html.erb
<head>
<%= include_gon %>
</head>
# app/assets/javascripts/application.rb
require 'native' # To be able to convert JS objects to hashes.
current_user = User.new(Hash.new(`gon.current_user`))
说明:
gem 设置一个哈希值,该gon
哈希值将被 JS 对象化并放入浏览器中的 JS 运行时中。有关这方面的更多信息,请参阅有关它的Railscast(它仍然主要相关,没有太大变化)。
在浏览器中,该 JS 对象也被命名为gon
,因此gon.current_user
将是您在gon.push current_user: some_user
控制器操作(或 before_action 回调)中设置的任何内容。
但是我们需要使用 将其从 JS 对象转换为 Ruby 哈希Hash.new(gon.current_user)
,然后您可以将生成的哈希传递给User.new
调用。
重要的部分:您需要User
在 Opal 应用程序中开设课程。如果您的 Rails 应用程序设置了User
ActiveRecord 模型,您将无法重用它,因此您需要创建一个新模型,但如果它只是一个 PORO(普通 Ruby 对象),您可以添加以下内容初始化器的行:
Opal.append_path Rails.root.join('app', 'shared')
然后,您可以将希望在 Rails 应用程序和 Opal 应用程序中可用的 Ruby 代码放入app/shared
. 例如,您可以这样做app/shared/user.rb
:
class User
attr_reader :id, :name, :email
def initialize(attributes={})
attributes.each do |attr, value|
instance_variable_set "@#{attr}", value
end
end
end
在 Reactive-Record 中开箱即用。否则,您必须在客户端 + v8 预渲染引擎和服务器之间构建某种 api 以获取数据(这就是反应记录所做的。)您可以在标记为“的文件中查看反应红宝石和反应记录的代码同构...”有关更多信息,请参阅 React.rb Reactive-Ruby 分支自述文件。