如何在Rails中将参数传递给js.erb?

Mar*_*ton 2 javascript ruby ajax jquery ruby-on-rails

我想要一个ajax请求用传递的参数调用user控制器的xyz动作,stage然后将其附加,#the_box以便我可以执行条件操作,如阶段x追加@user.age,阶段y追加@user.age+1和阶段z追加@user.age-1.我应该怎么做?

我有一个html.erb文件包含这样的代码:

<center>
  <%= link_to "A", xyz_user_path, stage: "x", remote: true %>
  <%= link_to "B", xyz_user_path, stage: "y", remote: true %>
  <%= link_to "C", xyz_user_path, stage: "z", remote: true %>
</center>
<div id="the_box"></div>
Run Code Online (Sandbox Code Playgroud)

并且users_controller.rb

before_action :set_user, only: [ :xyz]

def xyz
    respond_to do |format|
        format.js {}
    end
end

private
def set_user
    @user = User.find(params[:id])
end
Run Code Online (Sandbox Code Playgroud)

xyz.js.erb就是我现在所拥有但不能处理参数所以它无法处理条件操作

$("#the_box").append("<%= @user.age%>");
Run Code Online (Sandbox Code Playgroud)

Ric*_*eck 5

其他答案将帮助你 - 让我解释一下


format.js

当你format.js用来过滤时mime types,开放括号基本上告诉Rails你想要执行一些自定义功能(因此它不会加载[action].js.erb默认值)

如果您只想调用[action].js.erb,则必须调用以下内容:

respond_to do |format|
   format.js #-> will just call [action].js.erb
end
Run Code Online (Sandbox Code Playgroud)

您需要阅读有关Rails mime类型(如何确定XHR请求)respond_to块的更多信息


@instance_variables

其次,您需要考虑@instance variables应用程序中的角色,从而考虑相关方法.

你遇到的主要问题是你正在调用@user一个没有定义它的方法 - 因此你可能会看到错误undefined method ___ for nil:NilClass或类似错误

你必须记住,Rails只是一个宝石 - 一系列在Ruby语言上运行的类.这意味着每次您希望对"对象"/数据片段执行方法时,您都可以在Rails应用程序中声明/创建对象:

def xyz
   @user = User.find params[:id] #-> sets the variable for the duration of the "instance"
   ...
end
Run Code Online (Sandbox Code Playgroud)

请注意变量的名称 - 实例变量.通过设置@user(实例变量总是用a定义@),只要调用定义变量的,基本上就可以让Rails访问其中的数据.

基本上意味着如果你设置@user = User.find,它将通过view从类的实例调用的和其他辅助方法可用


固定

最后,直接解决您的问题:

我希望ajax请求使用传递的参数阶段调用用户控制器的xyz操作,然后将其附加到#the_box,以便我可以执行条件操作,如阶段x append @ user.age,阶段y追加@ user.age + 1和阶段z附加@ user.age-1.我应该怎么做?

#config/routes.rb
resources :users do
   get "xyz/:stage" #-> domain.com/users/:user_id/xyz/:stage
end

#app/views/users/your_view.html.erb
<% links = [["A", "x"], ["B", "y"], ["C", "z"]] %>
<% links.each do |link, stage| %>
    <%= link_to link, xyz_user_path(user, stage: stage), remote: true %>
<% end %>

#app/controllers/users_controller.rb
Class UsersController < ApplicationController
   def xyz
      case params[:stage]
        when "x"
          @user.increment!(:age)
        when "y"
          @user.decrement!(:age)
      end
      respond_to do |format|
         format.js
      end
   end
end

#app/views/users/xyz.js.erb
$("#the_box").append("<%=j @user.age %>");
Run Code Online (Sandbox Code Playgroud)