我希望我的一些模型属性能够动态预定义。我有各种型号。现在我希望我的 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 ?
如何在这里使用强力参数?
请帮我解决..
答案 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
操作,您应该在Bill
或Resident
模型上创建一个使用事务创建的方法所有账单都在同一时间因为您可能想要创建每个账单或者没有。这样,您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
当然要小心这一点,因为你正在打开潜在的漏洞。