2

我对 Rails 很陌生,因此在同时处理 AJAX、UJS 和 Rails 时有很多困惑。我查看了 railscast,几个 SO 答案,尝试了 freenode 上的#rubyonrails IRC 频道。唉,我还是卡住了。

无论如何,这是我的问题。

所以我有两个模型,建筑和财产。属性belongs_to Building 和Building has_many 属性。

我已将外键添加到 Property 作为 building_id。

现在,在我的建筑模型中,我有一个方法:self.search(search) 并给出正确的地址(例如 999 Decarie),它将正确地从数据库中的 Building 表返回 building_id。

def self.search(search)
    #search.instance_variables.map {|v| "#{v}: #{search.instance_variable_get(v)}\n"}.join
    if ((search.nil?) || (search == ""))
        nil
    else
        search = search.to_s
        d { search }
        split = search.split(' ', 2)
        stnum = split.first
        d { stnum }
        stname = split.last
        d { stname }
        Building.where("streetno = ?", stnum).where("streetname = ?", stname).pluck(:id).first
    end
end

在我的属性部分 _form 中,我有一个 form_for 循环,它使用一个 collection_select 来允许用户选择任何建筑地址(例如 999 Decarie),(因此它呈现为一个选择/选项 HTML 下拉列表)。

<div class="field" id="selection">
   <%= f.collection_select :buildinginfo, Building.all, :half_address, :half_address, {:label => "Building Info"}%>
</div>  

那么,我该如何使用不显眼的 javascript/ajax

A、用户在表单中选择后立即获取集合select的选择值,并传递给上面提到的建筑模型方法(self.search(search)),该方法返回正确的建筑ID。

B. 立即获取该方法返回的建筑物 ID 并将其存储在表单上的隐藏字段中(对应于 Properties 模型中的 building_id 字段)。(在下面的代码中,我想将值 1 替换为建筑物 ID)

 <div class="field" id="selection_id">
         <%= f.hidden_field :building_id, :value => 1 %>  
      </div>    

因此,允许我的关联工作,以便当我删除建筑物时,其所有相关属性也会被删除。

如果您需要更多代码,请告诉我,我正在使用 Rails 4,非常感谢!

4

3 回答 3

1

阿贾克斯

在 Rails 中,Ajax的工作方式与 Web 上的其他任何地方完全相同 - 您使用 Javascript 发送异步请求,服务器处理并发送响应。

Rails 的诀窍是让你的代码尽可能地模块化,这就是为什么这些ujs东西经常在应用程序中使用。你最好在这里阅读Rails 的ujsajax 功能

一旦用户选择它

听起来你需要.on("change"

#app/assets/javascripts/application.js
$(document).on("change", function(){
   $.ajax({
       url: "your/path",
       data: {search: $(this).val()},
       success: function(data) {
           // ... do stuff here
       }
   });
});

这基本上会将请求发送到您的服务器,允许您根据需要处理响应。

立即获取方法返回的建筑物 ID 并将其存储在隐藏字段中

你会想要这样做:

#Ajax method
success: function(data) {
    $("#element").val(data);
}

这需要伴随respond_to控制器中的块,如下所示:

#app/controllers/your_controller.rb
respond_to :js, :json
def search
   @search = Model.search params[:search]
   respond_with @search
end

--

数据

有趣的一点 - 您可以使用这样的多个查询.find_by来代替:where

Model.find_by(name: value, name: value).pluck(:id)
于 2014-06-06T07:07:28.370 回答
0

感谢您花时间解释这个 Rich。

虽然您的方法很有意义,但我使用了不同的方法,因为我的最终目标只是在建筑物 (has_many) 和属性 (belongs_to) 之间创建关联,并且当我删除建筑物时,我还希望与它关联的所有属性也被删除。

因此,在创建/更新属性时,我需要将其添加到 Building.properties 数组中,该数组会自动更新属性的 building_id 字段。

这是我在 properties_controller 中的最终代码:

def create
  @property = Property.new(property_params)

  **b_id = Building.search(@property.buildinginfo)**
  **Building.find_by(id: b_id).properties << @property**

  respond_to do |format|
    if @property.save
      format.html { redirect_to @property, notice: 'Property was successfully created.' }
      format.json { render :show, status: :created, location: @property }
    else
      format.html { render :new }
      format.json { render json: @property.errors, status: :unprocessable_entity }
    end
  end
end

def update
respond_to do |format|
  if @property.update(property_params)

    **b_id = Building.search(@property.buildinginfo)**
    **Building.find_by(id: b_id).properties << @property**

    format.html { redirect_to @property, notice: 'Property was successfully updated.' }
    format.json { render :show, status: :ok, location: @property }
  else
    format.html { render :edit }
    format.json { render json: @property.errors, status: :unprocessable_entity }
  end
end
end

Building.search 功能(在建筑模型中):

    def self.search(search)

    if ((search.nil?) || (search == ""))
        nil
    else
        search = search.to_s
        split = search.split(' ', 2)
        stnum = split.first
        stname = split.last
        s = Building.where("streetno = ?", stnum).where("streetname = ?",  stname).pluck(:id).first
        s
    end
end
于 2014-06-07T05:42:30.167 回答
0

这是与此问题相关的示例,希望对您有所帮助。在此示例中,我们将验证电子邮件。

定义一个方法users_controller并将路由设置在routes.rb

class UsersController < ApplicationController

def check_email
    @email = User.exists?(:email=> params[:email])  
    respond_to do |format|
        if @email
         format.json { render json: @email }
        else
         format.json { render json: @email }
        end
    end
end

路线.rb get "check_email" => "users#check_email"

现在来到register.html.erb页面并添加javascript为:

$('#email').blur(function(){

var re = /[A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}/igm;

if($('#email').val().trim()=="" || !re.test($('#email').val()))
{
    $("#lbl_email").text("*Please enter a valid email address");
    $('#lbl_email').show();      
    return false;           
}
else
{
    $('#lbl_email').hide();

    $.ajax({
        type: "GET",
        url: "/check_email",
        data:{ email: $(this).val() },
        dataType: "json",
        success:function(data){
          $('#lbl_email').show(); 
          $("#lbl_email").text("*Oppss! Email already exists");
          return false;

        },
        error: function() {
            $('#lbl_email').hide(); 
        }
    });
}
});
于 2015-10-06T07:05:13.240 回答