簡體   English   中英

UJS,AJAX,Rails 4,form_for collection_select將值傳遞給方法並將值返回給表單

[英]UJS, AJAX, Rails 4, form_for collection_select to pass value into method and return value back to form

我對Rails非常陌生,因此在一起處理AJAX,UJS和Rails時會產生很多困惑。 我看過railscast,有幾個答案,在freenode上嘗試了#rubyonrails IRC頻道。 las,我還是被困住了。

無論如何,這是我的問題。

所以我有兩個模型,建築模型和財產模型。 物業歸屬到建築物和建築物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

在我的Properties部分_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.一旦用戶在表單中選擇集合,就獲取集合選擇的選定值,並將其傳遞給上述的建築物模型方法(self.search(search)),該方法將返回正確的建築物ID。

B.立即獲取方法返回的建築物ID,並將其存儲在表單上的隱藏字段中(與“屬性”模型中的building_id字段相對應)。 (在下面的代碼中,我想用建築物ID替換值1)

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

因此,允許我的關聯進行工作,以便在刪除建築物時,其所有相關屬性也將被刪除。

讓我知道您是否需要更多代碼,即時通訊使用Rails 4,非常感謝!

阿賈克斯

在Rails中, Ajax的工作原理與網絡上其他任何地方都完全一樣-您使用Java腳本發送異步請求,服務器處理並發送響應。

Rails的竅門是使代碼盡可能模塊化,因此為什么在應用程序中經常使用ujs東西。 您最好在這里閱讀Rails的ujs ajax功能

用戶選擇后

聽起來像您需要.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)

感謝您抽出寶貴的時間來解釋此Rich。

盡管您的方法有意義,但我使用了另一種方法,因為最終目的只是在Building(has_many)和Property(belongs_to)之間創建關聯,並且在刪除Building時,我也希望與其關聯的所有Properties也都刪除。

因此,在創建/更新屬性時,我需要將其添加到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

這是與此問題相關的示例,希望對您有所幫助。 在此示例中,我們將驗證電子郵件。

限定在一個方法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

route.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(); 
        }
    });
}
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM