0

我知道这是一个非常简单的问题,但我想我的大脑和 google-fu 今天不太好用。

假设我有一个活动,有注册人,他们可以使用一笔或多笔付款来支付活动费用。

我正在尝试创建与注册人(与活动相关联)相关的付款。
所以我的付款应该有registrant_idevent_id

我的 URL 看起来像这样:(嵌套路由)

http://mysite.com/events/1/registrants/1/payments/new

我的控制器看起来像:

def create
  @event = Event.find(params[:event_id])
  @registrant = Registrant.find(:first, conditions: {id: params[:registrant_id], event_id: params[:event_id]} )

  @payment = Payment.new params[:payment]
end

我知道有一种更好的方法可以做到这一点,但我在正确使用谷歌搜索的措辞上遇到了问题:)

我应该使用什么语法来.new自动识别event_idand registrant_id

4

2 回答 2

0

直接设置id属性不是很好的做法,因为 id 可能不引用实际的数据库行。正常的做法是使用 CanCan ( https://github.com/ryanb/cancan ),这似乎可以解决您的所有问题。

编辑:

如果您不使用任何类型的身份验证,那么我会将加载方法放在before_filters 中以保持清洁:

before_filter :load_event

def load_event
  @event = Event.find params[:event_id]
end

或定义一些时髦的通用加载器(不必要的元和复杂,不推荐):

_load_resource :event

def self._load_resource resource_type
   before_filter do
     resource = resource_type.constantize.find params[:"#{ resource_type }_id]
     instance_variable_set :"@#{ resource_type }", resource
   end
end
于 2013-05-03T14:16:01.437 回答
0

根据评论中的讨论,有几种方法可以解决这个问题:直接方式和 Rails 方式。

new_object = ClassName.new创建相关对象的直接方法是按照问题中的建议使用创建对象。然后获取创建对象的 id 并将其设置在现有对象上(existing_object.id = new_object.id如果需要额外的逻辑,直接使用或通过其他方法)。或者通过定义自定义初始化器在新对象上设置 id,例如:

class Payment
  def initializer id_of_registrant
    @registrant_id = id_of_registrant
  end 
...
end

这种方法的优点是它允许您分配可能来自具有不同类的一系列对象的注册人 ID,而无需处理不必要的或可能不正确的(对于您的解决方案)继承和多态性。

Rails 方式,如果您在注册人和“强制”之间始终有直接关系(1 对 1)付款是使用 has_many 或 belongs_to 关联,如 Rails 指南中所述:http: //guides.rubyonrails.org /association_basics.html

对于问题中的示例类:

class Registrant < ActiveRecord::Base
  has_one :payment
end

class Payment < ActiveRecord::Base
  belongs_to :registrant
end

您将需要使用适当的迁移来创建与此相关的数据库表和外键。例如:

class CreateRegistrants < ActiveRecord::Migration
  def change
    create_table :registrants do |t|
      t.string  :name
      t.timestamps
    end

    create_table :payments do |t|
      t.integer :registrant_id
      t.string  :account_number
      t.timestamps
    end
  end
end

当然,如果您的注册者只是选择性地进行支付,或者进行多次支付,那么您将需要考虑使用 has_many 关联。

使用 has 和 belongs 关联,您可以做一些不错的事情,例如:

 @payment.registrant = @registrant

如果您手动实例化了对象,或者

 @payment.new(payment_amount)
 @registrant = @payment.build_registrant(:registrant_number => 123,
   :registrant_name => "John Doe")

如果您希望自动填充关联。

Rails 指南有很多示例,但根据我的经验,只有尝试最适合您的实际用例的示例才能显示是否存在无法预料的限制。Rails 方法将使未来的查询和对象构建变得更加容易,但是如果您的对象关系模型非常松散,您可能会发现它变得限制性或不自然,并且等效的关联更好地使用您的附加业务规则手动编码。

于 2013-05-06T12:51:04.480 回答