This episode was essentially repeated in Railscast 016 Virtual Attributes. Despite it being a repeat, I decided to create a project for this Railscast because the following episode, 033, used it to make a Rails Plugin. Rather than make the plugin, I wanted to try creating my second RubyGem based on this plugin.
Although I was not aware of this while making the gem, there was another person who had the same idea. His gem is called jakewendt-stringify_time, but it hasn’t been updated four years. The gem I created integrates with the changes made to the Ruby on Rails framework since that gem’s creation.
Because this would be my second gem I have created, I thought I could just model this gem similarly to my first gem body_id. I created the basic gem files using
bundle gem stringify_time command. Then I edited the
.gemspec file to put in the basic information needed. The part I got confused about was at the part I was going to use
railtie. The Railscast simply extended ActiveRecord using the module created in the plugin. Instead of following my previous gem, I decided to try how it was made in the video. I copied the
StingifyTime module from the episode and extended ActiveRecord just like it was shown in the episode. I ran
rake release and had version
0.0.1 on RubyGems.org. That’s when I created the previous project from Episode 032 to try the gem out. The bad part was, it didn’t work.
After some searching around I noticed other gems did not use
extend method on ActiveRecord directly, but they used the
.send :include, StringifyTime method to call the include method on a module. So I tried to exchange
ActiveRecord::Base.send :include, StringifyTime
The problem was I blindly tried to copy and try this method without fully understanding why I was using
include instead of
extend. Include is used on an instance of a class to add methods, while extend is used to add methods to the class itself. At the same time, I searched my gem on RubyGems.org and discovered the Jake Wendt’s gem based on the same episode. I looked at his GitHub Repo and saw he had an
rails/init.rb. “Could this solve it?”, I thought. I applied the changes, and the
stringify_time method was being include in my rails app.
What is so interesting about creating this
stringify_time method is that you are writing a program in order to have it write another program. That’s the concept of metaprogramming at least. You could have defined each getter and setter method manually, but that isn’t practical when you have numerous attributes you need to do the same thing on. I have used metaprogramming when I made a
seed.rb file to fill up the database with records. These methods saves a lot of time if made correctly.
When I went to edit the date on the form, the date was not updating. This is still a problem I need to solve, and I have opened a question on StackOverflow to try to resolve this issue. While I wait for an answer I’ll keep moving to another Railscast.
Someone on StackOverflow suggested I try using the generated method via the Rails console. I tried to use the rails console, and the
due_at attribute was updated. I thought why was I able to update the attribute in the console, but not via the form. The answer was because I was not whitelisting the
:due_at_string param in the
task_params definition. This is to protect from mass assignment. So the data from the form was never reaching the model because it was being prevented by the controller. A silly mistake to overlook.