Rails view_context
Posted
技术标签:
【中文标题】Rails view_context【英文标题】: 【发布时间】:2022-01-20 02:25:23 【问题描述】:我无法理解 view_context。我目前正在我的应用程序中实现数据表,参考来自this video。
我不明白的是如何访问 view_context 的内容,即传递给数据表类。
def index
respond_to do |format|
format.html
format.json render json: UsersDatatable.new(view_context)
end
end
然后我在我的数据表类中访问它
def initialize(view)
@view = view
end
我正在使用一个名为 subscribem 的 gem。我声明了一个 Subscribem::Account 并将变量 current_account 传递给每个视图。在数据表类中我可以像这样访问它
def initialize(view)
@view = view
@current_account = @view.current_account
end
但问题是在控制器中,我添加了一些变量,例如
def index
@date = DateTime.now #or date=DateTime.now
respond_to do |format|
format.html
format.json render json: UsersDatatable.new(view_context)
end
end
我无法获取过去的日期或@date。
def initialize(view)
@view = view
@current_account = @view.current_account
@date = @view.date
end
提前谢谢好兄弟/姐妹
【问题讨论】:
【参考方案1】:理解视图上下文的关键是真正了解像 ERB 这样的模板引擎是如何工作的(它们在高层次上的工作方式几乎相同)。
您获取一个字符串(或缓冲区)和一个上下文,该上下文是您要插入到视图中的数据以及您可能想要使用的所有方法。
举个简单的例子:
require 'erb'
class Person
def initialize(first_name, last_name)
@first_name = first_name
@last_name = last_name
end
def get_binding
binding
end
end
template = "Hello my name is <%= @first_name %> <%= @last_name %>"
person = Person.new('John', 'Doe')
erb = ERB.new(template)
puts ERB.new(template).run(person.get_binding) # Hello my name is John Doe
由于我们使用Person
实例内部的绑定运行模板引擎,我们可以访问它的实例变量。它本质上与视图上下文的工作方式相同。这种“魔法”就是控制器的实例变量如何在视图和帮助程序中可用,以及为什么初学者最终会将它们与全局变量混淆。
但是在其他情况下,例如装饰器或序列化器封装仍然适用。 @date = DateTime.now
仍然是控制器的实例变量,如果你想访问它,你需要使用 instance_variable_get
来违反封装:
def initialize(view)
@view = view
@current_account = @view.current_account
@date = @view.instance_variable_get(:'@date')
end
声明一个访问器:
class UsersController
attr_reader :date
def index
@date = DateTime.now #or date=DateTime.now
respond_to do |format|
format.html
format.json render json: UsersDatatable.new(view_context)
end
end
end
class UsersDatatable
def initialize(view)
@view = view
@current_account = @view.current_account
@date = @view.date
end
end
或者改变你的类的接口,这样它就不需要插入另一个对象。
class UsersDatatable
def initialize(view, date: nil)
@view = view
@current_account = @view.current_account
@date = date
end
end
【讨论】:
非常感谢。我理解数据如何从控制器传递到模板引擎/视图的概念。为什么根据我的代码无法获得数据是由于封装的原因?我还没有尝试过声明访问器的方式,但是我使用会话参数来存储数据,并且可以在数据表类中访问它。这是个好方法吗? 并非如此。会话主要用于跨请求存储数据。由于它存储在 cookie 中,因此您还必须非常小心以避免溢出,因为它的大小非常有限。在其他方面,它非常类似于使用全局变量。我会向初始化程序添加参数并显式传递数据。以上是关于Rails view_context的主要内容,如果未能解决你的问题,请参考以下文章
markdown [rails:devise] Ruby on Rails的身份验证gem。 #ruby #rails
Rails:如何在 Rails 中为 Devise 设置密钥?