簡體   English   中英

如何從ApplicationController調用模型的where(…)方法

[英]How to call the model's where(…) method from ApplicationController

假設我有兩個模型:客戶模型和產品模型

客戶端的“用戶名”和“電子郵件”應為“唯一索引”,作為產品的“序列號”

當用戶在唯一索引的表單字段上鍵入時,我有一個onblur函數,該函數將帶有屬性名稱和屬性值的請求發送到控制器。 如果存在值,則會立即通知用戶。

在ClientController中,我編寫了一個函數來檢查其是否唯一,並返回-2表示錯誤,返回-1表示不存在,或者返回正數(id)(如果存在)。

def unique  
  if params[:attrName].blank? or params[:attrValue].blank?
    id = "-2"
  else
    cli = Client.where("#{params[:attrName]} = '#{params[:attrValue]}'").first
    if cli != nil
      id = cli["id"]
    else
      id = "-1"
    end
  end

  render :json => {
    :id => id
  }
end

由於許多原因(SQL注入漏洞,違反DRY的情況),這樣做不是很好,因為每個控制器將具有基本相同的方法。

我正在考慮在ApplicationController中編寫“唯一”函數,但是如您在上面看到的,如果它是客戶端,則應該能夠調用“ Client.where”,如果是產品,則應該能夠調用“ Product.where”。 我如何才能最“一般”且最安全地構建此功能? 我正在考慮原始SQL,但我認為這是一種幼稚的方法。

最好避免使用原始SQL。

這行得通嗎?

class ApplicationController < ActionController::Base
  def unique
    id = if params[:attrName].blank? || params[:attrValue].blank?
      -2
    elsif found = model_name.where(params[:attrName] => params[:attrValue]).take
      found.id
    else
      -1
    end

    render json: { id: id }
  end
end

你可以把在application_controller.rb然后在這兩個你的ClientsControllerProductsController你定義model_name的方法:

class ClientsController < ApplicationController
  def model_name
    Client
  end
end

class ProductsController < ApplicationController
  def model_name
    Product
  end
end

這將起作用,但可能不理想。 您可能想讓Rails通過使用find來提高模型是否存在以及用於驗證所需參數是否存在的強大參數來進行更多工作。

您可以將其移至模塊並使其返回ActiveRecord關系。 好處是以后可以將它與其他ActiveRecord relations起來,就像(注意,我在sql條件中使用? ,而不是直接給param)

#module
module UniqueRecord
  module ClassMethods
     def unique(params)
       where(params)
     end
  end

  def self.included(receiver) 
    receiver.extend         ClassMethods
  end
end

並在課堂上使用它

#client.rb
class Client < ActiveRecord::Base
  include UniqueRecord
end

#product.rb
class Product < ActiveRecord::Base
  include UniqueRecord
end

因此,現在您的兩個類都有unique可用的方法。

您可以根據獲得的鍵和值創建一個哈希,例如:您可以動態創建一個哈希來搜索電子郵件,例如

hash = {email: 'same@email.com'}

然后調用方法

Client.unique(hash)

如果願意,可以通過類名字符串來調用它

'Client'.constantize.unique(hash)

還有一件事,最好返回對象數組(如果找到)或空白數組(如果找不到)而不是-1,-2。 這將使您的api保持一致。 喜歡

Client.unique(hash).to_json

暫無
暫無

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

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