My name is Tyler. I'm learning Ruby on Rails. This is a blog for me to talk about what I've learned. I'm no longer completely new to Ruby and while I don't feel comfortable calling myself a coder or programmer yet, I am absolutely a Ruby Enthusiast and a Rails Fancier. I've been working with Ruby on Rails since February 1, 2011. You know that song about "lovin' every minute of it?" Bingo.
Sunday, January 22, 2012
CODETOBER, other code-related things I've been up to
This applies to coding because they want a way to more accurately track where their users are coming from, so this week I'm going to look into coding something that will pull various bits of information into a more readable format. Sound cool, right?
I've also got an interview at iGoDigital on Tuesday, for a junior developer position. I interviewed there back in September, but it wasn't a good fit at the time. Now? Maybe a better fit! It's kind of funny. When I first got into Ruby, I wanted to make more money and programming seemed like a good way to do that. Now I'm less concerned about making more money, and I largely want to become a better programmer. Working full-time would definitely help me improve my skills, especially in a team environment. So I'm pretty excited about this opportunity.
I'm still gathering ideas for CODETOBER, since I really need to a) code more and b) blog about coding more. So far my list is pretty sparse, and I'm still open to suggestions if you've got them. What kind of things should I be looking into? What would be worthwhile, or valuable, or fun, or frustrating, or otherwise teach me a life lesson? I'd like to see more developers doing crazy things in February.
Now I think I'll sit down and work on a stupid project. I'm kind of losing interest in Dungeon Crawler (SURPRISE!)
Thursday, January 12, 2012
Announcing CODETOBER
But I've got an idea to remedy this. I absolutely SHOULD be blogging more often, and I'm going to take a page from my friend Miles' book and try to learn something new every day in February and then blog about it. I want to have an awesome name for this month, so I'm probably just going to call it CODETOBER. Also it's a leap year this year. WEIRD!
I've got a list going for things I want to look into or try to understand a bit. Mostly things I've heard mentioned often enough that I want to look into them, or how to use tools I'm already familiar with more effectively.
This list is pretty short, though. I'm definitely interested in learning how to dry up my code, since I feel that's a big weak point for me. And getting more familiar using Git for source control, learning more terminal shortcuts, Sass, Cucumber, HTML5 (since I'm a sucker for front-end design anyway) and I'm interested in getting more recommendations. What do you think would be beneficial to look into? Useful gems, fun tutorials, etc? I'M COUNTING ON YOU, INTERNET!
In more concrete coding news, I hung out with my friend Eli and he showed me how to dry up my Dungeon Crawler code quite a bit. I've now got one method that generates the rooms as opposed to 10 different methods! Still pretty soggy around the edges, though. And through the middle. It's actually mostly still pretty soggy.
Tuesday, January 3, 2012
Learning How to Abstract Code
The problem was due to a couple of things. First, I'd gotten a lot of really good advice that I didn't quite understand, and I felt bad that I wasn't getting it, so I was reluctant to ask for more advice. Second, I'd already spent so much time without making any progress that I was getting sick of the project.
But I think I've gotten through my lack of motivation and I've made some progress with this project, but the code is an explicit, redundant mess. So the question at this point becomes is it better for me to make some progress coding in a way that I know is bad, or to not make progress at all?
Obviously it's better to make progress (and I did learn a bit about YAML tonight, so it's not entirely a wash) but it's about time I got better at writing code. I've noticed a problem with the way I write code: I'm far too heavy handed and I repeat myself too much. I need to get better at abstracting my code, so that's my current goal.
Maybe this is easier said than done, but at least I'm losing track of time while coding again, right?
Friday, December 30, 2011
How do you deal with coder's block?
This is extra irritating because I'm pretty sure I DO get how routing with Sinatra works, but starting a user out on one page with an input form, then redirecting that user to another page based on his input, seems to be escaping me.
I've gotten this to work in a limited capacity, when all of the logic is thrown into the
get '/input' do
method, but using a case/when statement here always uses the same logic. For example, dais_room will be north of torch_room, but vine_room will be north of dais_room, and I was always being redirected to dais_room with input "go north."
I also had a problem of simply being redirected to a white page with black text pulling the description of the room. I believe this was the method @netshade showed me for automatically creating a room without explicitly coding it, but for some reason it was not loading a view file.
Here's a full gist of what I've got, if anyone wants to give me some srs help:
Dungeon Crawler full gist
What do you guys do when you get so frustrated with a project? Do you power through, work on something else, or just take a break? I feel like since the holidays began, I've found a ton of great excuses not to code. It's Christmas Eve! It's Christmas! I just had LASIK surgery done!
But I'm sick of making excuses and I want to get back into working on a project without feeling like a gigantic dummy or just tearing my hair out because I can't figure it out. That makes sense, right?
It's not all bad news, though. @netshade and @annamul gave me The Pragmatic Programmer, a philosophical/theoretical book about coding. I really like the PragProg guys, and this book has been a lot of fun to read so far.
I think I need some way of setting goals for myself each week with coding. As in, "This week get better with using Git for source control," or "This week, get more comfortable with Javascript." Any recommendations for simple goal setting applications, or methods you've used? I use Tadalist for simple day-to-day chores and things, but that's not quite what I want. Maybe Evernote would work? I still haven't checked into that.
Either way, thanks for all your help, everyone! And Happy New Year!
Monday, November 7, 2011
Random Name Generator with Ruby
My friend Eli showed me how to refactor the code so it was less specific and therefore much more versatile. Whereas the code I wrote was very specific to one MadLib, the one Eli helped me write is far more general, and can make MadLibs out of any text file that's been prepared (substituting all instances of a noun with NOUN, or NOUN1, NOUN2, etc, for repeating nouns)
It's obvious to me how valuable separating logic and data is, but it's going to take some work for me to really wrap my head around this. I've been coding with my logic and data entwined in a big hot nasty mess for a while.
Here's a gist of the finalized, objectified MadLibs generator:
MadLibs Generator
So my next goal is to take what I learned with refactoring the MadLibs generator and make another stupid project. I ran across this site a few nights ago:
Video Game Name Generator
So I've decided to build one using Ruby. I'm calling it aan so far (adjective, adjective, noun) and I've got a version working that will generate random combinations from pre-defined arrays, but I'm working on expanding it so it will read text files and generate lists from those files.
Once I get THAT up and running, I want to work on making it a bit more complex. Adding support for generating names that may or may not include a prefix or a suffix in addition to the standard adjective-adjective-noun, for example.
I think I'm having a lot more fun with coding when I'm working on stupid things like this than when I was working on larger-scale projects (long tutorials, Manticore, Chorenivore) but it's hard for me to objectively say which is more valuable.
Sunday, October 30, 2011
Refactoring Ruby Code
MadLib Generator, first version
It works, sure, but it's ugly. A ton of gets.chomp()'s, and there's obviously a better way to do it. Still, my plan was to hack it out as best I knew how, identify problems with it, and then rework the code.
So here's my second attempt:
MadLib generator, first refactoring
Not bad! I've gotten rid of all the gets.chomp() commands in favor of loops that will collect the correct number of nouns, verbs, adjectives and so forth. I also got rid of the prompt method - it's a hold over from the dungeon games I've been working on and I felt it was unnecessary. I was pretty proud of this, but my friend Eli thought it could be refined further, suggesting I try to Objectify the code. I'm a bit puzzled by this. What does this mean?
At any rate, I took another look and here's what I've got now:
MadLib generator, second refactoring
In this iteration, I cleaned up what's being collected a bit, and took out the definitions for popping words out of the arrays. I realized I could just call the .pop method directly by defining the array as an instance variable. This way, I was able to shorten the code by several lines by adding a character to each variable. Pretty good trade off, if you ask me!
I also redefined each array after calling a .reverse method on it. Since I'm using .pop to pull words out of the array to place in the Mad Lib, this will keep the words in the same order the user entered them.
Things are going pretty well. I feel proud that I'm anticipating problems and finding solutions for them now. Also, I should've been using Gists for a long time now.
Friday, October 28, 2011
Require - No Such File to Load Ruby
The way I picture it working is like this: the generator will ask the user to select a Mad Lib from a list, then ask for the requisite input (nouns, adjectives, verbs) depending on the Mad Lib selected and finally spit out the finished product. Simple, right?
So my thinking is this project would be split into two parts: the main program that asks for which Mad Lib the user wants to do, and the Mad Lib that is loaded upon selection. To get this up and running, I decided just to make one Mad Lib work at first, then add support for multiple Mad Libs and the ability to choose between them.
This is just a simple matter of requiring the Mad Lib file from the Main file, but I ran into a small problem.
Using the require 'mermaid' command threw this error:
I wasn't sure why this wasn't working, since I've used require to load separate .rb files before. After a bit of digging around, all I had to to do fix this problem is change require 'mermaid' to require_relative 'mermaid'. This makes sense - both files are in the same directory, so this command is simply saying to require this file located in the same directory as the main file.
On a side note, I'm glad to have fixed the problem, but I'm getting to the point that I think it's better to understand WHY things don't work, rather than finding the solution and moving on. Can anyone tell me why 'require' wasn't working, but 'require_relative' does? Is it an older style of Ruby code that's outdated? Do I need to change some configurations? Is require_relative a workaround? Where does require look for files, if not in the same directory the file that's making that call is located?
Anyway, it felt good to make some progress on this tonight. It's pretty awesome that I can come up with an idea on the way to work, come home and put it together in an hour and a half or so. I think this will be a fun little project. I plan to work on it more this weekend, expanding it, polishing it up and so on. Here's a link to the gist I made of it:
MadLib Generator
Sunday, October 16, 2011
Finished text-based adventure in Ruby
I've learned a lot with this little project: defining instance variables such as @brass_key, using instance variables to do things within other methods, such as opening doors, creating an inventory for the player that adds or subtracts items as they're found or used, logic to change events if certain instance variables were true and so on and so forth.
Tomorrow I plan to get back to work on Learn Ruby the Hard Way, but this week has definitely been well spent. I may revisit this project in the future and rewrite it to use case / while instead of if / elsif, but I'm ready to work on something new. I spend a lot less time flailing around and feeling stupid now and a lot more time coding or looking for ways to do what I want to do.
My vocabulary is getting better, too, so it's easier to find information now. And all of this work makes me think about Manticore (don't worry, baby, I haven't forgotten about you!) and how much easier it'll be to redo now. The code I had before I sat down with Eli a few weeks ago took me a couple of months to write, and I'm pretty confident I can get the same functionality with less code in about a week now. But first I need to finish up Learn Ruby the Hard Way.
And I've been thinking about using what I've learned to write tutorials. I'm sure other new Rubyists will be confused about local and instance variables, or how to write and call methods, and I'd like to try and write something up that will explain these basic ideas in the context of a text-based dungeon crawler. I haven't thought too much about it yet, but it's something I'd like to do in the future.
Here's a link to a gist of the game:
Dungeon of Unfathomable Horror
Tuesday, September 13, 2011
Validating integer ranges in Rails
Here's what I had before:
class Initiative < ActiveRecord::Base belongs_to :character validates_presence_of :dex, :misc, :speed validates_numericality_of :dex, :misc, :speed def total dex + misc end end
And I've changed it to:
class Initiative < ActiveRecord::Base
belongs_to :character
validates_numericality_of :dex, :misc, :speed
validates_inclusion_of :dex, :misc, :in => -10..20, :message => "must be between -10 and 20."
validates_inclusion_of :speed, :in => 20..200, :message => "must be at least 20."
def total
dex.to_i + misc.to_i
end
end
A pretty minor change, but here's what this is doing. First off, there's no need to validate both for presence_of and numericality_of an object. Validating numericality_of an object will in effect also validate_presence_of that object, since it must be an integer to pass validation.
Secondly, I've added a validates_inclusion_of to ensure that all integers make sense within Dungeons and Dragons rules. For example, :speed refers to how many feet a character can move per round. The vast majority of characters are going to be either 20 or 30, so I set 20 as the base. However, there are ways to get higher speeds, through class benefits, spells, magical items and so on, so I set the upper limit at 200. I don't use this object to make any calculations, but it's nice to have information that makes sense for a Dungeons and Dragons character, since Manticore is a Dungeons and Dragons character database program.
Lastly (and I think this might be a bit of overkill) I added .to_i to my logic, which will ensure all objects are integers before attempting to perform calculations. Am I right about this one? It also sets nil to 0, right? Pretty handy, considering I was wanting a way to set nil to 0 a while back.
I started to bang out a question, but as I was writing I got an idea of how to do what I want to do, so I'll give it a shot before asking for help
Sunday, September 11, 2011
Code abstraction with partials in Rails
I thought so, but here was the problem. I had some text that said "Add:" with links for items, spells, skills and so forth. I didn't want either the text or the link showing up unless the page hadn't been created. Only showing a link_to method if that page hasn't been created is easy, but I couldn't figure out a simple way of only displaying some text if all pages that could be created hadn't been created. An easier solution would have been just to axe the "Add:" text altogether, but I like it as a bit of guidance and separation.
This may be a case of me understanding partials well, so every problem appears to be a problem that can be solved with partials, but here's how I wrote the code.
First, I created a new partial, called "_menu_create" and threw it in the Characters view folder.
Here's the code for the partial:
Add:
<%= link_to 'Items Page', character_items_path(@character) unless @character.items.exists? %>
...
<%= link_to 'Background Page', new_character_background_path(@character) unless @character.background %>
And here's the method for rendering the partial:
<% unless @character.items.exists? and @character.skills.exists? and @character.specials.exists? and @character.spells.exists? and @character.background %>
<%= render 'characters/menu_create'%>
I feel like this is a bit over-engineered, especially since all it does that's different is not display the "Add:" text, but it works and I'm pleased with the result.
What's your opinion? Is there an easier way to do this? Is there also an easier way to group several conditionals together, so instead of writing the code as:
<% unless @character.items.exists? and @character.skills.exists? and @character.specials.exists? and @character.spells.exists? and @character.background %>
I could group all of these into a grouping called "conditions", and call something like:
<% unless @character.conditions? %>
Which would have the same effect? I'm guessing there IS something like this, and I just haven't run into it. I'm also getting the feeling I'm ready to move onto another project pretty soon, maybe running through more tutorials, or getting another book, or working on another personal project. Any suggestions? Should I keep working on Manticore? It's kind of hard to get a feeling for WHAT I should be working on, just that I should be working on SOMETHING. Crafting Rails Applications isn't quite what I was looking for, either. I was expecting something closer to Agile Web Development and it's more like a series of mini-tutorials, mostly for serious customization and I'm not quite ready for that jelly.
Tuesday, August 9, 2011
If and Unless Methods in Rails
Sometimes I sit down to code for an hour or two and everything I try either works right away, or is broken in such a way that the first fix I attempt works.
Today was one of those days! I had some minor successes straight off the bat, such as moving Delete methods into Edit methods, moving Edit methods into the Menu partial along with navigation and changing the Show method for Characters in the Index view to display character.name instead of a generic 'Show'.
But here's the big triumph of the heart tonight.
You may recall in my last post I was talking about how in the menu partial I didn't want to display pages that didn't apply to all characters. I don't want a spell tab in the menu for a character that doesn't learn spells, for example. So I figured out a way to solve this problem, and the really beautiful thing is the solution was maybe two lines of code. Why did I think this would be such a big deal?
Here's what I had originally:
<%= link_to_unless_current 'Special Abilities', character_specials_path(@character) %>
Changing this code so the Special Abilities page only shows up if it's been created is easy enough:
<%= link_to_unless_current 'Special Abilities', character_specials_path(@character) if @character.specials.exists? %>
But then I run into a problem. With the previous code, it was simple enough to create a Special Ability, since you just clicked on the Special Ability link and the show page would render the form, allowing you to create a Special Ability, or edit a previous Special Ability. So obviously I need to land a link to create that page somewhere.
The Character show page seems a logical choice, since it will exist before a Special Ability will, and a Special Ability's existence will depend upon a Character's existence, right? So let's wire that up:
<%= link_to 'Create Special Abilities Page', character_specials_path(@character) unless @character.specials.exists? %>
Making pretty good use of those if and unless methods!
I know Rails programmers often talk about how they can't believe something is so easy to do with Rails, but shit, I can't believe this was so easy to do. And it feels good to make this much progress on my own, because I feel like a lot of the time I'm just asking for help. This is a pretty good indicator that I'm figuring out how things work, where things go and how to make Rails sing and dance for me.
Monday, August 8, 2011
Working on personal Rails projects
The ability to create a new character, with several attributes includine statistics, hit points, armor information and so on.
The ability to create and destroy items that belong to said character.
The ability to create and destroy special abilities that belong to said character.
Not bad! I feel like I'm making some real progress here. Here's a few screen shots:
When I work on a Rails application (and especially when I work on one for myself) I like to keep a to-do list of features I want to implement. It feels GREAT to have a roadmap when working on any project, and Rails is no exception. Here's what I've got so far:
Add Skills - Every character will need skills, and I haven't started to tackle this yet because I'm not quite sure how to do it. I think simplest would be to make Skill a model with several defining attributes that belongs_to Character, with a has_many relationship. This would allow users to create skills as necessary, and not add Skills they either don't have or don't use. Actually, you know what? I just talked myself into doing it this way. BINGO!
Add Feats - Feats are going to be similar to Special Abilities, and I'm not sure if I want them to be in their own tab in the menu partial or lumped in with Special Abilities. I like the idea of keeping them separate, because some characters won't have Special Abilities, though most (if not all) characters will have Feats. I also don't want that menu partial to get too bulky.
Add Animal Companions / Spells - Here's another thing I want to do. As of right now, my menu partial displays the same things for all Characters (although some of these are just placeholder text) - Character | Items | Skills | Special Abilities | Spells - and it struck me the other day that I shouldn't be displaying these pages if the character doesn't have them yet. After all, a fighter doesn't learn spells or gain an animal companion, so why show them in the menu partial? So once I get some of these other relationships hammered out, I'll be looking for a way to add these, perhaps from the Character's view page, and have pages populate into the menu partial only if they've been created. Eventually I'll want the ability to drag and drop these to organize them by user preference, but let's not get too deep into the styling woods just yet.
And finally, I'll want to clean up the actual code I'm using. @unixmonkey showed me a way to get what I want done, but said it was messy and he was right. Still, it's more valuable to me right now to have code that works and not the most efficient code possible.
Remember when I said I find myself focusing more on my own projects than the tutorials and books I've been using? That still holds true.
Monday, July 11, 2011
Editing Functional Tests in Rails
Case in point:
I've been working through the Depot application with Agile Web Development with Rails. This latest chapter had me working through creating a mailer and writing tests for it. Creating the mailer went well, and I can use my own gmail account to send mail through my Depot application! SUCCESS!
However, I got hung up on the functional tests. And I know what the problem is, but not how to fix it.
Here are the errors I get:
1) Error:
test_should_destroy_line_item(LineItemsControllerTest):
ActiveRecord::RecordNotFound: Couldn't find LineItem with ID=980190962 [WHERE ("line_items".cart_id = 980190963)]
app/controllers/line_items_controller.rb:79:in `destroy'
test/functional/line_items_controller_test.rb:45:in `test_should_destroy_line_item'
test/functional/line_items_controller_test.rb:44:in `test_should_destroy_line_item'
2) Error:
test_order_shipped(NotifierTest):
ActionView::Template::Error: undefined method `protect_against_forgery?' for #<#
app/views/line_items/_line_item.html.erb:9:in `_app_views_line_items__line_item_html_erb___1505233713_2172764620_6072364'
app/views/notifier/order_shipped.html.erb:8:in `_app_views_notifier_order_shipped_html_erb___2127495373_2172826120_0'
app/mailers/notifier.rb:13:in `order_shipped'
test/functional/notifier_test.rb:13:in `test_order_shipped'
I have an idea why I'm getting the first error. I've been following the optional exercises at the end of each chapter and I changed the :destroy method in line_items_controller without updating the functional test. Here's the OFFENSIVE code:
def destroy
@cart = current_cart
@line_item = @cart.remove_product(@cart.line_items.find(params[:id]))
respond_to do |format|
format.html { redirect_to store_url }
format.js
format.xml { head :ok }
end
end
end
Any idea how to fix this? I'm not super concerned about it, but I'd like to know if I'm on the right track and I think this would be an easy fix. The second error I'm less sure about. I don't get why I'm getting an error for protect_against_forgery? since I'm not calling that method anywhere. Is it a default Rails thing that I'm overlooking?
Anyway, my current strategy has been simply to comment out the tests until later. Which may never come, depending on a variety of factors! I have a sneaking suspicion writing tests will never be one of my strong suits.
Getting back to my original point, it made more sense simply to comment these tests out rather than spend a bunch of time fixing them, especially since my application DOES work. Still, it's a good idea to get a handle on writing tests. I'm doing this for Future Tyler.
Wednesday, June 1, 2011
A little one-on-one with jqr
You want to talk about productive? In about an hour, Eli had shown me ways to solve both of the problems I've been having with Chorenivore and Manticore (I promise not all of my projects will end in an -ore sound) as well as digging into some more abstract theory stuff.
Basically what I've got now is a hidden_field and a couple of image_submit_tags that mark a task as finished or unfinished. We grabbed a couple of placeholder images, just so I could see how it worked and fired it up. BOOM! Marking a task as Finished displayed a nice little check mark, whereas marking a task as Unfinished displayed a little boxy box.
Question:
Here's the code for my hidden field in the Task view:
<%= f.hidden_field :finished, :value => !task.finished %>
From this syntax, my understanding is the hidden field is marking the task as finished or unfinished without being displayed to the user. Is this correct? How else is a hidden_field used?
After work, I decided I'd fire up Illustrator and Photoshop and see if I couldn't make a couple nicer looking little icons. Here's what I came up with at first:
What? Are you drunk? Look, I like big icons as much as the next guy, but 80 x 80 is just egregious. Let's shrink that down a little, son.
Aha! Now it's starting to come together. Plus, to use these images, all I had to do was throw them in the public/images folder, then call either 'finished.png' or 'unfinished.png'.
Not bad for Chorenivore!
Here's a little recap of the problem I ran into with Manticore a while back. David had shown me how to create instances of related models from my Character view that are tied to my main Character model. But once I got everything straightened out that I want displayed in the Character view (hit points, combat information, statistics, saves) I hit a wall. I wanted a way to link to another page within the same application that would display different information. For example, every Character will have Items. Items will be broken down into Weapons, Armor, Magical Items, Gear and Treasure.
The solution was this:
<%= link_to_unless_current 'Armor', character_armor_path(@character, @character.armor) %>
See, I KNEW I could do something like this, but the exact syntax was giving me trouble. But now that I know how to link to the view of a model that belongs_to another model, I can design the navigation fairly easily. You just throw that bad boy into a partial and call it macaroni!
I know working on functionality before worrying about style is the way to go, but I still have a hard time not thinking about how I want an application to be navigated.
So what did I take away from this, besides concrete Rails techniques? The internet is a great and valuable resource, but actually hanging out with and talking to people about projects is irreplaceable. Not only did Eli show me how to do some things I've been struggling with for about a month, but I also talked to all the Fastest Forward guys about projects they're working on. It's awesome to see people excited about what they're doing.
Monday, May 30, 2011
Gettin my git on
I also started using Git Hub, after almost three years of having an account. I understand how commits and pushing changes work, but I had some trouble last night. I was able to create a repository and upload the readme file, but then I couldn't get the entire project uploaded.
So here's what I think happened. I'm working with Chorenivore (my to-do list application) and I created a new directory at users/tylermoore/chorenivore, ran git init, tossed a README file in there and pushed it to git. Then when I went to upload the whole project, I was trying to push from users/tylermoore/code/chorenivore. Obviously having duplicate directories is a stupid idea!
So if I want to make a folder into a Git directory, ready for upload, all I have to do is navigate to that directory in terminal and use git init? Or do I need to make a brand new directory every time, then copy all my code into it? It seems like I should just be able to set up the necessary files with an existing directory. Also, what does git touch do? Can you just enter git touch . to touch everything in the directory?
In more concrete code-related news, Chorenivore is coming along pretty well. After creating the initial files with a scaffold (something my friend Matt says is a bad idea, even at early stages, and while I DO agree with him, I'm still finding it useful) I was able to edit the default code to do a few things I wanted to do. For example:
After creating a new Task, the user is taken back to the Task index page. A user is also taken back to the Task index page after deleting a Task and a flash :notice is displayed.
Creating a new Task does not allow a user to mark a Task as complete, but Editing a Task DOES allow this. Since scaffold generates New and Edit actions that use the same form, I simply copied the code and modified it so the boolean column for Finished? wasn't included.
Not bad! I've definitely got an application that works and functionality that makes sense. I think I've been good about thinking about how things should work, but actually making that happen is getting easier.
Oh, here's my git profile.
Monday, May 9, 2011
This code is...problematic
I'm still having trouble with my Manticore app. Basically, here's what I'm trying to do:
I have two models, Character and Statistic. Each Character will have_one Statistic, and Statistic belongs_to Character. So good so far, right? I want to be able to create the Statistic information from the Character view, then be able to edit that information once there's information to be edited. I want to only be able to create one instance of Statistic per Character, hence the has_one relationship.
One solution I got on Stack Overflow was to simply make a form in the Character view, but since I'll be extrapolating this code (once I finally understand it) to create other models like Equipment, Skills, Spells and so on, it doesn't make sense to load down the Character view with a ton of different forms.
I've been modeling the code for Manticore from this tutorial which has you create a blog. It was easy enough to see that Character could be substituted for the Post model, and Statistic could be substituted for the Comment model.
However, I've hit a wall. Now I get this error:
undefined method `build' for nil:NilClass
And I'm not sure why. I suspect it has something to do with the has_one vs. has_many relationship. Earlier, I'd followed the tutorial more closely, but I need to define the Character/Statistic relationship as has_one vs. has_many because I don't need multiple instances of Statistics per character. Any ideas where this error could be coming from? I'm not defining a build action, but this error never popped up before.
Here's some code, if that helps:
class Character < ActiveRecord::Base
has_one :statistic, :dependent => :destroy
end
class Statistic < ActiveRecord::Base
belongs_to :character
end
As far as I can tell, the model code is fine. But I might be missing something pretty obvious.
Here's code from the Statistics controller.
def create
@character = Character.find(params[:character_id])
@statistic = @character.statistics.create.new(params[:statistic])
redirect_to character_path(@character)
end
I may have something wrong here, but like I said, this has worked in the past and has tied the Statistic to the specific Character (something I was struggling with before this mess!)
This is from the Statistics _form partial:
<%= form_for([@character, @character.statistic.build]) do |f| %>
<div class="field">
<%= f.label :strength %>
<%= f.text_field :strength %>
</div>
...
<%= f.submit %>
</div>
<% end %>
I suspect my troubles may be coming from this code, but I don't get why. I'm following the tutorial and this has worked before, and all I've changed is the has_many relationship to a has_one.
In other less concrete news, I feel pretty dumb for just not getting this. However, in the course of trying to figure it out, both on my own, through people I know and asking and reading questions on Stack Overflow, I've got a much better grip on other things, like the overall MVC hierarchy, how partials work, how views work and so on.
I think part of what's keeping me interested in Ruby and Rails is how difficult it is for me. Coding is not something I have a great natural talent for, so I really have to work to make progress. Still, I'm proud of what I've learned so far and there is no shortage of great, helpful people in addition to a treasure trove of information available, so I'm confident I'll get where I want to be. Sooner or later.
Another problem I've had is describing exactly what I want to do. I think in the future, I'll benefit greatly from mapping projects out better beforehand as well as learning how to describe my ideas better.
Sunday, April 17, 2011
+3 to Code Spear
Remember when I would just delete the entire project and start over because I'd screwed the code up so bad and had no idea how to fix it? Yeah, me too. (It was last week) But those days are over!
So here's my game plan: blast all the way through Agile Web Development for Rails, then get back to work on Manticore. Probably a good time to start using Git as well. It shouldn't take me too long to finish up this book, considering I've had it less than a week and I'm already 100 pages in. My progress with this book is definitely faster than my progress through Learning Ruby, probably due to a combination of AWB4R being much more practical and having some experience under my belt now.
On a side note, I spent maybe 6 to 8 hours working on Rails this weekend and I still feel like I'm not doing enough. I have a suspicion most developers feel this way no matter how much code they're writing.
Thursday, April 14, 2011
Agile Web Development with Rails
I picked up a copy of Agile Web Development with Rails this week. I even sprang for a hard copy, despite my philosophy against owning physical media. Seriously, cavemen had books. Look it up. Anyway! I finally got a chance to sit down with it this evening. (Saying "finally" here is funny, since I just got it yesterday, but couldn't do anything with it since the Indy RB meetup was last night)
STILL, "finally" feels appropriate, considering I spent all day at work foaming at the mouth to get home and start coding. So far I really like the book. Like Beginning Ruby, it's written in an easy to follow, engaging manner with practical examples. Is there any other way to write a coding book? Probably not if you want people to read it. So far a lot of what I've seen in the book is refresher material for me, since I've spent the last couple of weeks doing Rails work by following online tutorials and working on Dungeon Roller.
Still, I've already learned some helpful things. Such as having two terminal windows open: one to run the Rails server of my project, and one to perform tasks. I had no idea! It simply did NOT occur to me that I could have two windows open. Another helpful tidbit came with generating a controller. If you write the code as such:
rails generate controller Say hello goodbye
Rails creates a controller named Say, with two empty methods inside of it: hello and goodbye. This definitely saves time later, because up until now I'd been writing methods by hand. Finally (and this is getting into code theory, but we're talking kiddie pool stuff here) I learned the idea that the controller holds the data and the view displays it. Pretty basic, but essentially even though you CAN write code directly into the view, it's a better idea to have the controller handle it. This idea is similar to separating raw HTML from styling.
On a side note, I've decided to rename Dungeon Roller to Manticore, both as a nod to Dwight from the Office and in homage to my favorite mythological creature.
Monday, April 11, 2011
Dungeon Roller progress
Once you click through on a character, this is what you see:
Now say you want to click through on Statistics:
But here's the problem. The individual characters are all using the same instance of the Statistic model. I haven't worked with the other models yet, but I'm assuming this would be true for them as well. How do I need to edit the code so each Character has a separate Statistic, instead of the same Statistic being shared?
Here's my code from the routes.rb file:
DungeonRoller::Application.routes.draw do
resources :combats
resources :saves
resources :statistics
resources :characters do
resources :combats
resources :saves
resources :statistics
end
And some code from the models:
class Character < ActiveRecord::Base has_many :statistics has_many :combats has_many :saves end And each of the other models have: class Statistic < ActiveRecord::Base
belongs_to :character
end
I thought associating these as has_many would solve the problem, but apparently I was wrong. Any input on this would be greatly appreciated!
Saturday, April 9, 2011
Model misbehavior
I'm working on Dungeon Roller and I've created two models: Character and Statistic. What I want to do is have Statistic display under Character. So logically I need to associate these models such that Character has_one Statistic model and Statistic belongs_to Character, right? These associations (has_one, has_many, belongs_to and has_and_belongs_to_many) all refer to how many of those models can display the model they're associated with, right?
If I can get this relationship figured out, and make it so that Statistic will display on Character and remain separately editable, I can use that as a template to hammer out other models I've got planned. I'll eventually have 7 or 8 models that belong to the main Character model. I ran into some trouble earlier when I named Character as Characters, not realizing that is not the way to do things. I also ran into some trouble with reserved keywords. I had "class" as a string in the Character model and eventually figured out I couldn't use it.
So while today's been frustrating because I haven't made as much progress as I'd like to, I got those two things figured out at least.





