In my Ruby on Rails project I have a module called Node. In that module I have different classes such as playback
, if
, hangup
, etc. They are created using Node::Playback
, for example. Each of these classes has different required attributes. Node has the following declaration as part of it:
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
As an example, playback
, declared as class Node::Playback
, has the following in its model:
class Node::Playback < Node
acts_as_node [ :body, :author ]
end
In my view for creating a playback node, I want to loop through all the required attributes, ie [:body, :author]
. It is important that I do this dynamically and not hard code it because Node has many different classes, not just playback.
= 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'
In the above code, @node_type.required_attrs returned [:body, :author]
when I byebugged it in the controller. I also checked that the elements in the array are of class 'Symbol'. @new_node
was created using Node.new(callflow: @callflow)
and @node_type
was created using "Node::Playback".constantize
f.label ra
would put the correct label in my view(ie. correctly put a label in my form when I comment out the line below it). However, when I did f.text_area ra
or f.text_area(ra)
it would say undefined method body' for #<Node:0x00007f271df3bc18>
Any suggestions?
@new_node
appears to be an instance of Node
. I don't see a definition for @node_type
, but based on the error, I'm assuming it's a Node::Playback
instance.
The Node
instance won't have the required attributes of Node::Playback
, so when you ask the form renderer f
(which represents a Node
instance) to render the required attribute ra
of a Node::Playback
instance you're getting the error.
Try this instead:
= 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)
Then make sure that the @new_node
instance is of the appropriate type (eg Node::Playback
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.