簡體   English   中英

如何在 Rails 中傳遞動態參數?

[英]How to pass dynamic params in Rails?

我希望我的一些模型屬性動態預定義。 我有各種模型。現在我希望我的比爾模型使用其他模型實例創建對象。

楷模 :

    leave.rb        # belongs_to :residents
    resident.rb     # has_many:leaves,has_many:bills,has_one:account
    bill.rb         # belongs_to:residents
    rate_card.rb    # belongs_to:hostel
    account.rb      # belongs_to:resident
    hostel.rb       

現在這是我的賬單控制器創建方法:

def create
    @bill = Resident.all.each { |resident| resident.bills.create(?) }
    if @bill.save
      flash[:success]="Bills successfully generated"
    else
      flash[:danger]="Something went wrong please try again !"
    end
  end

我想使用所有模型構建賬單,例如:

resident.bills.create(is_date:using form,to_date:using form,expiry_date:using form,amount:30*(resident.rate_card.diet)+resident.rate_card.charge1+resident.rate_card.charge2)+(resident.account.leaves)*10+resident.account.fine)
///////Is this possible ?

以及如何在這里使用強參數?

請幫我解決thxx ..

create需要一個哈希值,你可以:

create_params = { amount: 30*(resident.rate_card.diet) }
create_params[:some_field] = params[:some_field]
# and so on
resident.bills.create(create_params)

或者:

obj = resident.bills.build(your_strong_parameters_as_usual)
obj.amount = # that calculation
obj.save!

我對您的控制器語法感到困惑。 @bill被設置為循環的值,感覺@bill 每個循環都返回您循環遍歷的可枚舉項,因此您最終會得到@bill = Resident.all並在旁邊創建一些賬單。

您的管理員真正想知道的是,我的許多新賬單是否正確保存?

這似乎是使用 ruby​​ 對象(或者,通俗地說,一個普通的舊 Ruby 對象,而不是 ActiveRecord 對象)來封裝這個賬單生成器的細節的完美地方。

如果我沒看錯的話,您似乎正在根據表單輸入的數據一次生成許多賬單,例如:

  • is_date
  • to_date
  • expiry_date

...以及有關每個居民的一些數據。

這是我要創建的模型:

應用程序/模型/bill_generator.rb

class BillGenerator
  include ActiveModel::Model
  # This lets you do validations

  attr_accessor :is_date, :to_date, :expiry_date
  # This lets your form builder see these attributes when you go form.input

  attr_accessor :bills
  # ...for the bills we'll be generating in a sec

  validates_presence_of :is_date, :to_date, :expiry_date
  # You can do other validations here. Just an example.

  validate :bills_are_valid?

  def initialize(attributes = {})
    super # This calls the Active Model initializer
    build_new_bills # Called as soon as you do BillGenerator.new
  end

  def build_new_bills
    @bills = []
    Resident.all.each do |r|
      @bills << r.bills.build(
        # Your logic goes here. Not sure what goes into a bill-building...
        # Note that I'm building (which means not-yet-saved), not creating
      ) 
    end

  def save
    if valid?
      @bills.each { |b| b.save }
      true
    else
      false
    end
  end

  private

    def bills_are_valid?
      bill_validity = true
      @bills.each do |b|
        bill_validity = false unless b.valid?
      end
      bill_validity
    end

end

為什么這一切都是亂七八糟的? 因為在你的控制器中你可以做...

應用程序/控制器/bill_controller.rb

def create
  @bill_generator = BillGenerator.new(bill_generator_params)
  if @bill_generator.save?
     # Redirect to somewhere with a flash?
  else
     # Re-render the form with a flash?
  end
end

def bill_generator_params
  params.require(:bill_generator).permit(:is_date, :to_date, :expiry_date)
  # No extra garbage. No insecurity by letting all kinds of crud through!
end

...就像BillGenerator是任何舊對象。 保存了嗎? 偉大的。 它沒有,再次顯示表格。

現在,我的BillGenerator不僅僅是復制和粘貼。 你的“build_new_bills”可能會有你提到的一些數學,我會留給你。

讓我知道你的想法!

我認為,如果您想要在createupdatedelete計算屬性(意味着依賴於其他模型的屬性),那么您想要的這種邏輯的 Rails 方式是使用callbacks 例如:

class Bill < ActiveRecord::Base
  ...
  before_create :set_amount

  ...

  protected

    def set_amount
      self.amount = 30 * self.resident.rate_card.diet + self.resident.rate_card.charge1 + self.resident.rate_card.charge2 + (self.resident.account.leaves) * 10 + self.resident.account.fine
    end
end

如果您希望在更新記錄時也使用此邏輯,那么您應該使用before_save而不是before_create

執行此操作后,您應該接受 Bill 模型的常用參數(強),如下所示:

def bill_params
  params.require(:bill).permit(:is_date, :to_date, :expiry_date)
end

所以你的create調用會是這樣的:

resident.bills.create(bill_params)

此外,請注意您的create操作,您可能應該在BillResident模型上創建一個方法,該方法使用事務同時創建所有帳單,因為您可能希望創建每個帳單或不創建所有帳單。 這樣你就不會在BillsController使用Resident.all.each邏輯。

你可以通過使用params.permit!params.permit! 因為這允許傳遞任何參數。 這是一個例子:

def create
  ...
  @bill = Resident.all.each { |resident| resident.bills.create(any_params) }
end

private
def any_params
  params.permit!
end

當然要小心這一點,因為你正在向潛在的漏洞開放。

暫無
暫無

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

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