rails 将参数或变量传递给多个控制器操作
rails pass params or variable to multiple controller actions
我有一个显示多个 "principals" 的下拉菜单,当用户选择主体并点击提交时,表单将主体 ID 参数传递给控制器操作。
问题是我需要在多个控制器中使用该参数值。
我的观点
<div class="row">
<div class="col-sm-12 button-wrapper">
<%= form_tag(principal_analytics_path, method: 'get', class: 'form-inline justify-content-center') do %>
<%= select_tag 'prid', options_from_collection_for_select(Principal.all, :id, :name), :prompt => "Select Principal", class: "form-control wrapper-space" %>
<%= submit_tag "Search", class: 'btn btn-primary wrapper-space', :name => nil %>
<% end %>
<%= link_to "Clear", principal_analytics_path, class: "text-danger" %>
</div>
</div>
控制器动作
一旦我获得选定的主体 "books",我就需要一种将 @pri_books 变量从一个控制器传递到另一个控制器的方法。或者只是将“params[:prid]”传递给多个控制器操作的方法。我不知道该怎么做。也许是将变量从一个控制器传递到另一个控制器的函数?
# displays graphs about principals.
def principal_analytics
@months_back = 12
if params[:prid].present?
# takes a principals id as a parameter.
# @months_back will determine how many months are shown in the chart.
@pri_books = Book.principal_books(params[:prid], @months_back)
end
respond_to do |format|
format.html
format.js {}
format.json { render json: {success: true}}
end
end
您可以使用从控制器返回的数据来填充隐藏的表单元素 (hidden_field
)。这些字段会将它们的值作为 params/data 提交给表单的操作,就像任何其他表单元素一样。注意:这是不安全的,很容易被用户操纵,所以如果担心这一点,请不要使用此方法。
或者,您可以将这些数据存储在 Rails' session 变量中。该会话在服务器中维护,可用于跨多个请求存储数据。请注意,要正确执行此操作,您应该确保有一个明智的方法来使会话数据过期或删除,以避免 (1) 保留比您需要的更多的数据,以及 (2) 混淆用户体验,他们期望一个新的空白表单但是之前多次点击填充的数据。
我最终让它工作的方法是制作一个 class 级别变量 @@class_variable
然后将其设置在接收参数的控制器操作中,然后我可以在其他控制器操作中使用这些参数.
虽然不确定这是否是正确的方法,但它确实有效。
# class level variable outside of any action
@@principals_books = nil
# displays graphs about principals.
def principal_analytics
@months_back = 12
if params[:prid].present?
# takes a principals id as a parameter.
# @months_back will determine how many months are shown in the chart.
@pri_books = Book.principal_books(params[:prid], @months_back)
# set the data from the local instance variable to the class variable
@@principals_books = @pri_books
end
respond_to do |format|
format.html
format.js {}
format.json { render json: {success: true}}
end
end
def another_action
@local_variable = @@principals_books
@local_variable.do_something
end
使用会话变量,这就是它们的用途...
session[:prid] = params[:prid]
你甚至可以在你的 ApplicationController
中设置一个方法,在你需要的时候给你本金...
class ApplicationController < ActionController::Base
def current_principal
principal.find_by(id: session[:prid])
end
end
现在只需在需要的地方使用current_principal
。 (如果您还没有选择,它将是 nil
)
我有一个显示多个 "principals" 的下拉菜单,当用户选择主体并点击提交时,表单将主体 ID 参数传递给控制器操作。
问题是我需要在多个控制器中使用该参数值。
我的观点
<div class="row">
<div class="col-sm-12 button-wrapper">
<%= form_tag(principal_analytics_path, method: 'get', class: 'form-inline justify-content-center') do %>
<%= select_tag 'prid', options_from_collection_for_select(Principal.all, :id, :name), :prompt => "Select Principal", class: "form-control wrapper-space" %>
<%= submit_tag "Search", class: 'btn btn-primary wrapper-space', :name => nil %>
<% end %>
<%= link_to "Clear", principal_analytics_path, class: "text-danger" %>
</div>
</div>
控制器动作
一旦我获得选定的主体 "books",我就需要一种将 @pri_books 变量从一个控制器传递到另一个控制器的方法。或者只是将“params[:prid]”传递给多个控制器操作的方法。我不知道该怎么做。也许是将变量从一个控制器传递到另一个控制器的函数?
# displays graphs about principals.
def principal_analytics
@months_back = 12
if params[:prid].present?
# takes a principals id as a parameter.
# @months_back will determine how many months are shown in the chart.
@pri_books = Book.principal_books(params[:prid], @months_back)
end
respond_to do |format|
format.html
format.js {}
format.json { render json: {success: true}}
end
end
您可以使用从控制器返回的数据来填充隐藏的表单元素 (hidden_field
)。这些字段会将它们的值作为 params/data 提交给表单的操作,就像任何其他表单元素一样。注意:这是不安全的,很容易被用户操纵,所以如果担心这一点,请不要使用此方法。
或者,您可以将这些数据存储在 Rails' session 变量中。该会话在服务器中维护,可用于跨多个请求存储数据。请注意,要正确执行此操作,您应该确保有一个明智的方法来使会话数据过期或删除,以避免 (1) 保留比您需要的更多的数据,以及 (2) 混淆用户体验,他们期望一个新的空白表单但是之前多次点击填充的数据。
我最终让它工作的方法是制作一个 class 级别变量 @@class_variable
然后将其设置在接收参数的控制器操作中,然后我可以在其他控制器操作中使用这些参数.
虽然不确定这是否是正确的方法,但它确实有效。
# class level variable outside of any action
@@principals_books = nil
# displays graphs about principals.
def principal_analytics
@months_back = 12
if params[:prid].present?
# takes a principals id as a parameter.
# @months_back will determine how many months are shown in the chart.
@pri_books = Book.principal_books(params[:prid], @months_back)
# set the data from the local instance variable to the class variable
@@principals_books = @pri_books
end
respond_to do |format|
format.html
format.js {}
format.json { render json: {success: true}}
end
end
def another_action
@local_variable = @@principals_books
@local_variable.do_something
end
使用会话变量,这就是它们的用途...
session[:prid] = params[:prid]
你甚至可以在你的 ApplicationController
中设置一个方法,在你需要的时候给你本金...
class ApplicationController < ActionController::Base
def current_principal
principal.find_by(id: session[:prid])
end
end
现在只需在需要的地方使用current_principal
。 (如果您还没有选择,它将是 nil
)