【问题标题】:Update query for instance variable更新实例变量的查询
【发布时间】:2014-12-26 11:23:45
【问题描述】:

在一些帮助下,我现在可以将参数传递给控制器​​中的方法。我现在坚持的是如何使用该方法并将其分配给我的实例变量。

class PublicController < ApplicationController

def rehome
  @animals = Animal.animals_rehome.paginate(:page => params[:page], :per_page => 6)
    respond_to do |format|
     format.html
     format.js
    end
 end

def rehomed
  respond_to do |format|
   format.js {render :json => Animal.where(animal_type: params[:animal_type]) }
 end
end

使用以下 ajax 帖子更新参数

$('select.btn').on('change', function() {
  var animal_type = $('#animalType option:selected').text();
  var animal_town = $('#animalTown option:selected').text();

  $.ajax({
   type: 'POST',
   url: '/public/rehomed',
    data: {
     animal_type: animal_type,
   },
    success: function(data) {
     console.log(data);
    }
    });
  });

我想要实现的是在初始页面加载时使用

def rehome
 @animals = Animal.animals_rehome.paginate(:page => params[:page], :per_page => 6)
end

但是当通过选择下拉菜单选择我想要的过滤器时

 def rehome
  @animals = rehomed.paginate(:page => params[:page], :per_page => 6)
 end

但我不确定如何设置。

编辑

我的设置现在看起来像

class PublicController < ApplicationController
 before_filter :default_animal

def rehome
  respond_to do |format|
   format.html
   format.js
  end
end


def rehomed
 conditions = {}
 conditions.merge!(animal_type: params[:animal_type]) if params[:animal_type].present?
 conditions.merge!(rehomed: params[:rehomed]) if params[:rehomed].present?
 conditions.merge!(users: {town: params[:animal_town]}) if params[:animal_town].present?

 @animals = Animal.joins(:user).where(conditions)

  respond_to do |format|
   format.js { render json: @animals }
  end
end


private

def default_animal
  @animals = Animal.animals_rehome.paginate(:page => params[:page], :per_page => 6)
end

end

每次下拉列表在视图中更新时,我的 ajax 请求都会发送正确的参数来构建 @animals 查询,而我想要实现的是将新查询的结果加载到与will_paginate 结构(如果可能的话)。

   $('select.btn').on('change', function() {
    var animal_type = $('#animalType option:selected').text();
    var animal_town = $('#animalTown option:selected').text();
    var data_send = { animal_type: animal_type, animal_town: animal_town, rehomed: false}


   if(animal_type == 'All') {
    data_send = {animal_town: animal_town, rehomed: false}
   }
  if(animal_town == 'All') {
   data_send = {animal_type: animal_type, rehomed: false}
  }

  $.ajax({
   type: 'POST',
   url: '/public/rehomed',
    data: data_send,
     success: function(data) {
      console.log(data);
     }
  });
 });

查看rehome.html.erb

 <div class="all_animals">
  <%= render @animals %> # this is in a partial called _animal.html.erb
 </div>

 <div id="infinite-scrolling">
   <%= will_paginate @animals %>
 </div>

rehome.js.erb

$('.all_animals').append('<%= j render @animals %>');
 <% if @animals.next_page %>
  $('.pagination').replaceWith('<%= j will_paginate @animals %>');
 <% else %>
  $(window).off('scroll');
  $('.pagination').remove();

【问题讨论】:

  • 请求之间不存储实例变量。您必须为每个请求重新创建状态。为此,您需要保留辅助数据(例如,当前页码或动物类型)。通常这是通过查询字符串完成的。
  • 你能否提供一个例子来说明你的意思,不太理解你的解释
  • 他的意思是每次你想显示从 rehomed 在@animals 中查询的更新值时,你需要创建一个新请求,一种方法是更新 jQuery 的 @ 中的视图/HTML 987654332@回调。
  • 我什至不知道从哪里开始,你知道任何给出例子的文献吗..
  • 首先,在调用 rehomed 之前调用了 default_animal,这意味着已经设置了 @animals。然后,您将在重新设置的操作 @animals = Animal.joins(:user).where(conditions) 中覆盖它的值。我的意思是,也许你不需要在 rehomed 中调用过滤器。不太清楚如何做,但如果你渲染部分会更容易。在 rehomed 操作中呈现 rehome 布局,并在 ajax 请求返回时将该视图插入到您的 html 正文中。它会自动更改分页。 @animals 必须在 rehomed with pagination 中设置

标签: jquery ruby ajax json ruby-on-rails-4


【解决方案1】:

你应该使用 before_filter

class PublicController < ApplicationController
  before_filter :filter_method

    def rehome
        respond_to do |format|
         format.html
         format.js
        end
     end

    def rehomed
      respond_to do |format|
       format.js {render :json => @animals.where(animal_type: params[:animal_type]) }
     end

    private
    def filter_method
      @animals = Animal.animals_rehome.paginate(:page => params[:page], :per_page => 6)
    end
end

您需要 params[:page] 和 params[:animal_type] 来执行重新定位的操作

更多关于before_filter

【讨论】:

  • 所以我只能在 rehome 操作上调用 before_filter 然后 rehomed 将是 @animals.where(:page =&gt; params[:page], animal_type: params[:animal_type])
  • 在上面的代码中, before_filter 在每个动作之前被调用,它必须像这样才能检索'@animals'实例变量的值。正如@sergio 在评论中所说的“实例变量不存储在请求之间。您必须为每个请求重新创建状态......”每个动作都发生在一个请求中。对您的 rehomed 操作的请求不会请求 rehome 操作,但它们都使用 before_filter 不重复自己(DRY)
  • 感谢您的解释。我仍然遇到的问题是,当我使用 will_paginate 和无限滚动实现时,在“卡迪夫”中搜索“猫”时,所有参数都正确传递,但是当我向下滚动页面时,它默认返回@animals 的原始过滤器方法分配(即它显示了根据animals_rehome 范围内的所有动物)
  • 您能用代码的当前状态更新您的问题吗?这与问题无关,但我想指出您应该使用诸如 index、show、edit、update 和 destroy 之类的操作名称,因为它更易于阅读,并且它是 rails 的标准。我也建议你试试Agile Web Development With Rails Book :)
  • 感谢您对书籍的建议,感谢.. 我知道 CRUD,我在这里所做的与 CRUD 无关.. 不过我会更新我的问题,希望您能提供帮助跨度>
猜你喜欢
  • 1970-01-01
  • 2014-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-30
  • 2014-10-05
  • 2017-10-17
  • 2021-02-07
相关资源
最近更新 更多