如何在Rails中传递动态参数?

时间:2016-04-20 17:39:33

标签: ruby-on-rails ruby database activerecord

我希望我的一些模型属性能够动态预定义。我有各种型号。现在我希望我的 Bill 模型使用其他模型实例创建对象。

模特:

    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 ?

如何在这里使用强力参数?

请帮我解决..

4 个答案:

答案 0 :(得分:1)

我对你的控制器语法感到困惑。 @bill被设置为循环的值,感觉不到。每个循环返回你循环的可枚举数,所以你最终会得到@bill = Resident.all,并且会在旁边创建一些账单。

您的控制器真正想知道的是,我的许多新帐单是否正确保存?

这似乎是使用ruby对象(或者,通俗地说,是一个Plain Old Ruby对象,而不是ActiveRecord对象)来封装这个bill-generator的细节的理想场所。

如果我正确读到这一点,看来您根据表格输入的数据一次生成了多张账单:

  • 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'可能会提到你提到的一些数学,我将留给你。

让我知道你的想法!

答案 1 :(得分:1)

如果您希望创建更新 计算属性,我认为您希望此逻辑的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

执行此操作后,您应该接受比尔模型的常用参数(强),如:

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

所以你的create电话就像:

resident.bills.create(bill_params)

另外,要谨慎对待create 操作,您应该在BillResident模型上创建一个使用事务创建的方法所有账单都在同一时间因为您可能想要创建每个账单或者没有。这样,您Resident.all.each中就不会有BillsController逻辑。

答案 2 :(得分:0)

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!

答案 3 :(得分:-1)

您可以使用params.permit!来执行此操作,因为这样可以传递任何参数。这是一个例子:

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

private
def any_params
  params.permit!
end

当然要小心这一点,因为你正在打开潜在的漏洞。