I am using Ruby on Rails 3.0.7 and I am trying to implement an act_as_article
plugin for my application开发者_运维百科. What I would to do is run validation methods for the "acting as article class" inside that plugin (note: my plugin requires to create some database table columns in order to work - one of these is represented by the title
attribute).
In my RoR application I have this code:
# vendor/plugins/article/lib/acts_as_article.rb
module Article
extend ActiveSupport::Concern
included do
validates :title, # Validation method
:presence => true
end
module ClassMethods
def acts_as_article
send :include, InstanceMethods
end
end
module InstanceMethods
...
end
end
ActiveRecord::Base.send :include, Article
# app/models/review.rb
class Review
acts_as_article
...
end
Using the above code the plugin works. However if I add some Record Association in the Review
class like this:
class Review
acts_as_article
has_many :comments # Adding association
...
end
and in my ReviewsController
I add the following, as well:
def create
...
@article.comments.build( # This is the code line 89
:user_id => @user.id
)
if @article.save
...
end
end
I get this error
NoMethodError (undefined method `title' for #<Comments:0x00000103abfb90>):
app/controllers/articles_controller.rb:89:in `create'
Probably it happens because the validation run for all Review
"associated" classes\models and the Comment
class doesn't have the title
attribute. I think that because if inside the plugin code I comment out the validation method like this
module Article
...
included do
# validates :title, # Validation
# :presence => true
end
...
end
I don't get errors anymore.
So, how can I solve this issue?
Note: I am not expert on creating plugin (this is my first time), so I ask implicitly also if I'm doing a good job for the plugin implementation...
You are including validates_presence_of :title in ActiveRecord::Base, and thus every active record model is picking it up. Instead, you should do:
# vendor/plugins/article/lib/acts_as_article.rb
module Article
extend ActiveSupport::Concern
module ClassMethods
def acts_as_article
validates :title, # Add validation method here
:presence => true
send :include, InstanceMethods
end
end
module InstanceMethods
...
end
end
So that you only include the validation on ActiveRecord models that expect the validation to go through. Let me know if this solves your issue.
精彩评论