为什么控制器需要实例变量来使用ajax

Asa*_*uhi 4 ajax ruby-on-rails railstutorial.org

在rails教程的第12.2.5节中,引入了Ajax以"在不离开页面的情况下异步发送请求到服务器".respond_to然后在控制器中使用该方法,以允许具有启用的javascript的浏览器使用Ajax,或者在禁用Ajax的情况下使用重定向进行响应.

用于在两个用户之间创建关系的表单是:

<%= form_for(current_user.active_relationships.build, remote: true) do |f| %>
  <div><%= hidden_field_tag :followed_id, @user.id %></div>
  <%= f.submit "Follow", class: "btn btn-primary" %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

关系控制器中的相应操作是:

  def create
    @user = User.find(params[:followed_id])
    current_user.follow(@user)
    respond_to do |format|
      format.html { redirect_to @user }
      format.js
    end
  end
Run Code Online (Sandbox Code Playgroud)

使Rails有机会使用Ajax的方法是remote: trueform_forhelper方法中添加.根据教程,控制器必须使用实例变量@user而不是局部变量user在表单中使用remote: true.

如果没有Ajax,除了remote: true代码缺失之外,生成的表单将是相同的,并且在控制器中respond_to,代码部分将被redirect_to替换; 而且,实例变量@user可以被局部变量替换user,因此create动作将是:

  def create
    user = User.find(params[:followed_id])
    current_user.follow(user)
    redirect_to user
  end
Run Code Online (Sandbox Code Playgroud)

我想知道:为什么控制器必须使用@user实例变量而不是局部变量user才能使用Ajax?我尝试使用局部变量,实际上需要刷新才能看到任何变化.@user表单中使用的变量在@user.id用户控制器的show动作中定义,因为表单本身的部分插入show.html.erb文件中.因此,据我所知,@user用户控制器和@user关系控制器之间没有任何关联.

Fab*_*uda 5

您需要将其声明为实例变量(@),以便它在您的视图中可用.是的,使用ajax你没有重新加载页面,但你发回js而不是html.rails会响应任何内容create.js.erb.请注意,在此文件中,您需要访问@user数据; 如果您将其声明为user代替@user,则无法访问:

#app/views/relationships/create.js.erb
$("#follow_form").html("<%= escape_javascript(render('users/unfollow')) %>");
$("#followers").html('<%= @user.followers.count %>');
Run Code Online (Sandbox Code Playgroud)