Это, вероятно, больше проблем, чем это стоит, и является опасным, поскольку он включает в себя переопределение метода Credit
класса initialize
, но я думаю, что это может сработать. Моим советом для вас было бы попробовать решение, которое я предложил раньше, и отбросить эти драгоценные камни или изменить их, чтобы они могли использовать ваш метод. При этом ничего не говорится:
Сначала вам нужно получить способ вызова метода для инициализатора кредита. Давайте используем класс I found on the web called CallChain
, но мы его модифицируем для наших целей. Вероятно, вы захотите положить это в свою папку lib
.
class CallChain
require 'active_support'
def self.caller_class
caller_file.split('/').last.chomp('.rb').classify.constantize
end
def self.caller_file(depth=1)
parse_caller(caller(depth+1).first).first
end
private
#Stolen from ActionMailer, where this was used but was not made reusable
def self.parse_caller(at)
if /^(.+?):(\d+)(?::in `(.*)')?/ =~ at
file = Regexp.last_match[1]
line = Regexp.last_match[2].to_i
method = Regexp.last_match[3]
[file, line, method]
end
end
end
Теперь нам нужно переписать Credit
классов инициализатора, потому что, когда вы делаете вызов Credit.new
или Credit.create
из другого класса (в данном случае вашего Image
класса), он называет инициализатору от этого класса. Вы также должны убедиться, что, когда вы делаете звонок Credit.create
или Credit.new
, который вы передаете в :caller_class_id => self.id
аргументу атрибутов, так как мы не можем получить его от инициализатора.
class Credit < ActiveRecord::Base
#has a field called name
has_many :images
attr_accessor :caller_class_id
def initialize(args = {})
super
# only screw around with this stuff if the caller_class_id has been set
if caller_class_id
caller_class = CallChain.caller_class
self.send(caller_class.to_param.tableize) << caller_class.find(caller_class_id)
end
end
end
Теперь, когда мы имеем эту установку, мы можем сделать простой метод в нашем Image
классе, который будет создавать новую Credit
и настройки ассоциации должным образом:
class Image < ActiveRecord::Base
belongs_to :credit
accepts_nested_attributes_for :credit
# for building
def build_credit
Credit.new(:attr1 => 'val1', etc.., :caller_class_id => self.id)
end
# for creating
# if you wanted to have this happen automatically you could make the method get called by an 'after_create' callback on this class.
def create_credit
Credit.create(:attr1 => 'val1', etc.., :caller_class_id => self.id)
end
end
Опять же, я действительно Wouldn Я рекомендую это, но я хотел посмотреть, возможно ли это. Попробуйте, если вы не возражаете переопределить метод initialize
на Credit
, я считаю, что это решение, которое соответствует всем вашим критериям.
«Кредит» - это как кредит на фильм (атрибуция) в отличие от кредита на счете (оплате), правильно? – jefflunt
Да, извините. 2,5 года, работая в редакции, исказил мой жаргон. –