В моем проекте Ruby on Rails у меня есть модуль под названием Node. В этом модуле у меня есть разные классы, такие как playback, if, hangup и т. д. Они созданы, например, с использованием Node::Playback. Каждый из этих классов имеет разные обязательные атрибуты. В составе Node есть следующее объявление:
class Node < ActiveRecord::Base
...Other irrelevant code
class << self
attr_accessor :required_attrs
attr_accessor :optional_attrs
def acts_as_node required_attrs=[], optional_attrs=[]
@required_attrs = required_attrs
@optional_attrs = optional_attrs
(required_attrs + optional_attrs).each do |attr|
attr_accessor attr
end
required_attrs.each do |attr|
validates attr, presence: true
end
end
end
end
Например, playback, объявленный как class Node::Playback, имеет в своей модели следующее:
class Node::Playback < Node
acts_as_node [ :body, :author ]
end
На мой взгляд, для создания узла воспроизведения я хочу перебрать все необходимые атрибуты, то есть [:body, :author]. Важно, чтобы я делал это динамически, а не кодировал жестко, потому что в Node много разных классов, а не только для воспроизведения.
= form_for([@callflow, @new_node]) do |f|
h2 | Fill All Required Attributes Below
- @node_type.required_attrs.each do |ra|
.form-group
= f.label ra
= f.text_area(ra)
h2 | Fill Optional Attributes Below
- @node_type.optional_attrs.each do |oa|
.form-group
= f.label oa
/= f.text_area oa
.form-group
= f.submit class: 'btn btn-success'
В приведенном выше коде @ node_type.required_attrs вернул [:body, :author], когда я исправил его в контроллере. Я также проверил, что элементы в массиве относятся к классу «Символ». @new_node был создан с использованием Node.new(callflow: @callflow), а @node_type был создан с использованием "Node::Playback".constantize.
f.label ra поместил бы правильную метку на мой взгляд (т.е. правильно поместил бы метку в мою форму, когда я закомментировал строку под ней).
Однако, когда я делал f.text_area ra или f.text_area(ra), он говорил: undefined method body' for #<Node:0x00007f271df3bc18>
Какие-либо предложения?






@new_node, по-видимому, является экземпляром Node. Я не вижу определения для @node_type, но на основании ошибки предполагаю, что это экземпляр Node::Playback.
Экземпляр Node не будет иметь обязательных атрибутов Node::Playback, поэтому, когда вы просите средство визуализации формы f (которое представляет собой экземпляр Node) отобразить требуемый атрибут ra экземпляра Node::Playback, вы получаете сообщение об ошибке.
Попробуйте вместо этого:
= form_for([@callflow, @new_node]) do |f|
h2 | Fill All Required Attributes Below
- f.object.required_attrs.each do |ra|
.form-group
= f.label ra
= f.text_area(ra)
Затем убедитесь, что экземпляр @new_node относится к соответствующему типу (например, Node::Playback).
Я думаю, ваш макрос
acts_as_nodeдолжен быть объявлен какdef self.acts_as_node required_attrs=[], optional_attrs=[]