Showing posts with label rails. Show all posts
Showing posts with label rails. Show all posts

Thursday, January 26, 2012

Using Twitter Bootstrap to Render Partials with Tabs

It's been a good week for coding. I've done some pair programming, interviewed at iGoDigital, and dug into Twitter Bootstrap.

Which is actually the topic of this post! WEIRD!

Anyone ever tried using those sexy little tabs to render partials? Basically I'm working on Chorenivore again, and I want a tabbed view of the days of the week, with each tab containing items that are supposed to be done that day. I'm currently thinking of a separate partial for each day, though this could probably be reduced to one partial that simply renders each chore that's been tagged with the day of the week, but I thought I'd make it stupid before I made it clean.

Here's the specific code I'm talking about:

Twitter Bootstrap Tabs

I understand how to switch through actual links just fine using these tabs, but how would you do the same thing with partials? I found this question on StackOverflow that seems to address this, but I couldn't get his example to work.

Here's a link to Chorenivore on Git:

Chorenivore on GitHub

A couple other things. First off, I haven't really used Rails in the last four or five months and it feels so BULKY compared to Sinatra. I'm all "WTF, how do I link to a new view and actually make it do right?"

And does anyone know where I'd find Why's Poignant Guide to Ruby? I feel a book report coming on.

Tuesday, January 24, 2012

Resurrecting an old project

Have you ever been thinking so hard about a problem that you don't even notice when the music you're listening to has stopped playing? This just happened to me about five minutes ago, while I was looking through the code for my old project Chorenivore.

I'm thinking about getting back to work on it for a couple of reasons. Working on a more concrete app that does a few very specific things is both more useful and easier to do than spending my time coding a game, like Dungeon Crawler. I've tried to find a good to-do application, but haven't had any luck. I've tried Tadalist, ToodleDo and Remember the Milk.

And it's a good idea to work on a project to solve a problem I have.

Problem? I don't like the to-do applications I've tried.
Solution? Make one yourself, dummy!

What I want Chorenivore to be is a simple to-do application that allows users to create single and repeating tasks. I also want users to determine when a task should be completed upon creation.

Then I want a list of the days of the week, which allows users to drill down and see what's due that day. I may want some other visual cues in the future (such as showing how many tasks are due on a particular day, or separating single and repeating tasks) but for now I'll be satisfied with tabs that render partials for each day of the week.

The real thing I think is missing from online to-do lists is the satisfaction of crossing an item off a list. I often find myself making lists simply so I CAN check things off of that list. I'm sure I'm not the only one, so I'm thinking about ways to replicate this, or get close to replicating it with a web application.

How often do you guys do something like this? Dig up an old project you've abandoned for one reason or another? I'm guessing this is a pretty regular occurrence for web developers.

On a side note, I fired up a new Rails application the other day and it's funny how BULKY Rails seems after a solid 3 or 4 months using Sinatra.

Sunday, October 2, 2011

Using Ruby to Solve Problems

This past week I've been working through Learn Ruby the Hard Way. It's really a great resource (as I've mentioned a few times already) and I'm picking up lots of good habits. Here's a little example:

I work full-time doing SEO for an e-commerce site, and a while back we ran into a problem on our site with duplicate content. We needed a simple tool for entering two blocks of text and calculating how similar they were as a raw percentage. We eventually found some tools, but they weren't quite what we needed and weren't that great.

So I got the idea of building something using Ruby to do just this and spoke to my friend Eli about it. I still haven't actually BUILT this little program (and I'm sure it WOULD be little, at least at first) and part of the reason was that I didn't have a great idea of HOW to build it. I assumed I might have one model, say Text, with two textarea fields that could be compared, then spit out a percentage for similarity.

Obviously, I'd be using Ruby to make this calculation and that would be a matter of defining a word, counting instances of words, and then making a comparison between both blocks of text.

I've been doing a lot of work using Ruby to open and edit files, so it's obvious I could do similar operations to open and compare files, then generate a report based on that comparison. Not an elegant solution, since users would want to paste text into fields and compare them, not upload files to compare. But I'm sure it's doable. So that might be my next project.

I kind of tend to bounce around between projects, but I'm learning the entire time, so I don't feel bad about it. That's what these projects are for, right?

I also tend to think of an idea, and immediately think of ways to expand it even before I have the original idea working. For example, I'm already thinking of how this project could be expanded to do other things with text, such as identifying words that are used too frequently, identifying passive voice, identifying and suggesting replacements for adverbs and so on. In this case, I think it's because the original problem seemed to be "How can we identify content that's too similar in terms of SEO?" but I've begun thinking of it as "How can we write better content for the web?"

From my limited experience and understanding of web development, programming and computer science in general, it seems to be a matter of identifying a problem and then finding a solution. Am I far off the mark here?

Monday, September 26, 2011

Updating to Rails 3.1 and Ruby 1.9.2

Yesterday evening I went over to @jqr's house for some Rails help and advice. Early into out discussion it became clear to me (and was probably already clear to Eli) that I should redo Manticore.

Here's where it stands now: A whopping 14 models. 14! Why, Tyler? Why did you do that?

Back when I first started working on this project (in April or May I believe) making things that belong_to a Character, such as Hit Points, Armor Class, Statistics and the like, into separate models made more sense to me because they would be easier to edit. It didn't occur to me that if I only wanted to edit a Character's Hit Points, that I could simply render a form that ONLY had that field on it, and edit the record that way.

So after about 3 hours of talking and eating delicious cinnamon buns, @jqr showed me how to think about the problem in a different way. Rather than having modifiers that are specifically called from Statistics and applied to things like Fortitude Saves, or Attack Rolls, I'll have one method for ALL Modifiers, not a thousand different kinds of modifiers. I'm still rolling this around, trying to get a grip on it, but now that I've begun thinking about Manticore in a different way, I think I'll be able to make much more progress going forward. I already GET how to define methods and call them, as well as how to render partials and views that do a variety of tasks, so I'm most of the way there already, right?

Most of my time tonight was spent trying to get Rails 3.1 and Ruby 1.9.2 installed and cooperating. I was getting a ton of BOGUS errors, about Gems that Rails couldn't find. Turns out you have to install a bunch of crazy stuff for 3.1, like Sass, Sass-Rails, Coffee-Script and so on. WEIRD, right?

One cool thing I noticed: I went ahead and created a scaffold for my Character model, and made statistics into attributes of Character. All the statistics are integers, so when it pops up on the form, you get an automatic drop down that just inputs numbers. I'm guessing this is to get around people entering non-integers, and I bet I can pretty easily limit the scope of these attributes.

I don't think updating to Rails 3.1 and Ruby 1.9.2 was strictly necessary, but this seems like a good time to make a change. Also seems like a good time to get more comfortable (re: comfortable at all) writing and running my own tests, considering that's something I've woefully neglected.

Wednesday, September 21, 2011

Instance variables and local variables in Rails

I've got a lot to learn about local and instance variables. I already knew 'character' meant a local instance of character, but I thought '@character' referred to another model, and not an instance of the Character model. I knew that sometimes if Rails was complaining about an unidentified local variable, putting an @ in front would often fix the problem, but I didn't know why. I think I've got a better handle on this, but I think the time has come to do some serious background reading to try and patch up some of the holes in what I know and what I think I know.

On the other hand, thanks to help from @jqr and a healthy does of trial and error, I've gotten that pesky statistic bonus problem figured out. This is what ended up working:

def total
  fortitude_base + character.statistic.con_modifier + magic + misc
end

And here's the con_modifier definition from my Statistic model:

def con_modifier
  (constitution.to_i - 10) / 2
end


I'm keeping it as .to_i now, as a fix for a case where a player tries to create a Fortitude save before a Constitution score has been entered. The .to_i translates a nil record to 0, so Rails does a temporary calculation (which isn't shown) rather than displaying an error. Not sure if there's a better way to handle this (perhaps simply checking that statistic.constitution.present? before performing any calculations) but it works for now.

More importantly than simply figuring this one instance of how to define logic in one model and then call it in the view of another is understanding HOW it works. I can extrapolate these methods and apply them to other things: skills, attack rolls, armor class, etc, etc. Once again, Manticore proves to be a useful learning tool! SUCCESS!

Sunday, September 18, 2011

Nil can't be coerced into Fixnum in Rails

Question time!

I'm trying to figure out a way to calculate bonuses or penalties from a Character's Statistics, and then apply that method in other Models' views to calculate things like Fortitude saves, attack bonuses and so on. I've been working with a modifier for Constitution and here's what I've got so far.

The logic for calculating a Statistic bonus/penalty is (statistic - 10) / 2. So for a score of 14, we get 2, and for a score of 8, we get -1. Not bad so far!

So I define this method in Statistic controller:

def con_modifier
  (constitution.to_i - 10) / 2
end

And since I want to see it in my Character view, I wire it up in the Show method in Characters controller as such:

@con_modifier = @character.statistic.con_modifier

So I can see it in my Character view (where most of this information is displayed) and I know it's working so far. I've got a Fortitude model for Fortitude saves, and I'd like to use the con_modifier in the logic to calculate a total. How do I call a foreign model correctly this way? I have:

Here's the logic for calculating a total in my Fortitude model right now:

def total
  fortitude_base.to_i + ability.to_i + magic.to_i + misc.to_i
end

And I tried changing it to:

def total
  fortitude_base.to_i + @con_modifier + magic.to_i + misc.to_i
end

But then I get this error:

nil can't be coerced into Fixnum

So obviously it isn't calling up the correct information. I've noticed if I chage @con_modifier to @con_modifier.to_i, it calculates it at 0, because it's nil. Any ideas on how to call the number that actually exists? Do I need to define it in my Fortitudes controller as well, or can I simply define it in the Fortitude model and call it in the view that way?

Tuesday, September 13, 2011

Validating integer ranges in Rails

Taking my friend Matt's advice, I redid the validation and logic for my models in Manticore tonight. Didn't take too long and the new way makes more sense than before.

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

Monday, September 12, 2011

Code abstraction and models in Rails

I felt like I had a minor break through tonight, thanks in part to my friend Brent. Abstracting code using partials is something that's made sense to me for a long time. Basically, you're just cleaning up the code of a view by creating another bit of code that's called using a render method.

However, last night as I was writing some partials, I noticed I was loading quite a bit of logic into my view and it felt wrong, somehow. I felt...dirty. I was on the right track when I assumed there was a way to collect this logic into a method, then just call that method in the view, rather than having all the logic piling up, making an untidy mess of my code.

But I didn't quite get how to define a method in a model. Sure, I've defined methods such as:

def foo
  bar
end


But usually I got this code by following a tutorial, or reading through a book and so forth. It was never my code, and I think that was the reason I didn't really understand it. Now that a situation has arisen that I needed to learn how to write logic into a model and then call it in the view, I understand it. Funny how that works, huh?

Also, I don't think I'm quite as done with Manticore as I thought last night. I'm obviously still learning from working on it, and that's what I'm after. I've got some big ideas that are frankly a bit intimidating (user account creation and log-in, differing account types and permissions for dungeon masters and players, to name just two) but what's the best way to get over being intimidated by coding? By getting excited about coding. It's brought me this far, anyway!

Sunday, September 11, 2011

Code abstraction with partials in Rails

Abstraction was the name of the game tonight. As you many know, I have a _menu partial running across most of my pages. This partial links to a character, as well as his spells, skills, items and so on. I had a second area in the Character's view page that allowed users to add new pages, and the link would disappear once the page had been created. Why not move this create method up into the _menu partial and get it out of the Character's view page? That makes sense, right?

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.

Thursday, September 8, 2011

Navigation methods in Rails

I may not always feel like coding, but most of the time if I sit down to code I get warmed up and quickly forget I didn't feel like coding. Today was one of those days. I didn't feel like coding, but I took a look at my to-do list and figured "Hey, I can at least knock out some of this easy CSS stuff, right?" I try to live by a code of "Rails every day".

With that said, here's a little problem I've got.

Here's how I currently have a Back link written in my Menu partial:

<%= link_to 'Back', characters_path %>

The problem is, I render this partial on every page, and so the Back link shouldn't always point to characters_path. I thought an easy solution to this would be to write the code like so:

<%= link_to 'Back', :back %>

This returns the user to the last page viewed, which is closer to what I want, but then I run into some irritating navigational issues. Say you were looking at a Character's Items, and created a new Item, then hit the Back button once it was created. Since I'm rendering the form in the Items view page, it simply takes the user back to the previous view, showing a form with blank fields. So here's my question:

Is there an easier way to handle this? A better method than :back? Should I simply make two versions of the menu partial, each with a separate back link? I don't think I'll need more than two. The menu partial rendered when viewing a Character will want to point back to characters_path, whereas every other page (Items, Skills, and so forth) will need to point back to the Character view page. Maybe I'm overthinking this, considering it's just an extra partial, but I'm thinking there might be a better way to handle this. Imagine if I wanted five different menu partials, or twenty? I think it's better to think of more abstract solutions that can be applied to multiple scenarios.

Wednesday, September 7, 2011

More has_one model work in Rails

When it comes to coding, it seems like I've got good days, bad days, and frustrating days. Sometimes the Venn diagrams of these days overlap quite a bit. Take today for example.

I've been coding now for a little over 2 hours and I've finally gotten a problem straightened out. If you'll recall, I was attempting to build a Background for a Character, have it show up in my menu partial, and editable from there. I had a method that would build models with a has_many relationship to Character, but Background will have a has_one relationship and it was proving a bit trickier. I've more or less got it straightened out now (at least it's working on my local machine) so I've thrown it up on Heroku.

Manticore on Heroku

I've also done some more work, simplifying the data that's actually displayed in the view, while still allowing users to manipulate that data with an edit action. My reasoning is a user may always want to know what his total Armor Class is, but how often do you need to know what your Deflection modifier is? Not often, that's how! So basically, if you're rarely going to need it, why display it all the time? I think eventually I'd like to have an arrow users can click on that might expand that information, while displaying the bare minimum by default. I'm not sure what I'd use for this, but it sounds like a problem for Javascript.

Also, don't mind those saving throws! They refuse to work. What a lazy model! This merits a bit of examination. And I actually just realized it's not working when creating a new character on Heroku. Thanks, Heroku!

Still, it feels good to have this problem figured out. I've been wrestling with it for a while, and now I can move on to wrestle with other, more interesting problems! Like this mysterious SAVING THROW problem that's arisen. What could be going on here?

Absolutely LOVE crossing things off my list. Although I appear to have added several more. As usual.

Monday, September 5, 2011

Difference between build_model and create_model in Rails

I keep a note pad with features I want to add, things I need to fix and other reminders to myself whenever I'm coding an application. I've got a few methods defined in my models that will calculate totals. Needless to say, these methods aren't going to do anything but complain if the data fields they use to calculate a total either don't exist or aren't integers. What to do?

Validation to the rescue! But I had a problem. A minor problem. The models I speak of all belong to a main Character model. Take my Initiative model for example. It belongs_to Character, and Character has_one Initiative. I have a few fields in Initiative: :dex, :misc, and :speed. These refer to a Character's Dexterity modifier, any miscellaneous modifiers and how many feet that Character can move in a round. So I have this method defined in Initiative.rb:

def total
  dex + misc
end


This way, I can simply call Initiative.total in a view and Rails will calculate the total for me. Cool, right? And this is where validation comes in handy. However, here's the issue I had. My validation worked, but it was showing an error BEFORE any data had been entered. Definitely better than not working, or allowing a user to enter a B instead of an 8, but I'd rather not show an error message if no error has been made. So what was the solution?

First, the validation I wrote, in my Initiative model.

validates_presence_of :dex, :misc, :speed
validates_numericality_of :dex, :misc, :speed

This all looks good. I suspected the error was in the way my new method was written in Intiatives controller, but I couldn't figure it out, so I asked for help on StackOverflow. User m_x was kind enough to point me in the right direction.

def new
  @character = Character.find(params[:character_id])
  @initiative = @character.create_initiative(params[:initiative])
end


This bit of code was the culprit. Easy enough to fix, though.

def new
  @character = Character.find(params[:character_id])
  @initiative = @character.build_initiative(params[:initiative])
end


It turns out the reason my validation was being called before a user had entered any data is because the create method creates a new object and attempts to save it. In this case, it wasn't saving because it failed the validation, because nothing had been entered yet. On the other hand, the build method creates a new object, but does NOT save it. Easy enough to remember! As an added bonus, this gives me some ideas on how to tackle another problem I've been thinking about.

This mistake feels like something I should have known before hand, considering how much time I've spent reading through the Rails API, but I have a hard time holding on to information until it becomes practical. But now that I've used this, and cemented exactly what the difference is between build_model and create_model, I won't make the same mistake again.

One less thing, right?

Wednesday, August 31, 2011

Alphabetical sort method in Rails

So the other day, frustrated with the complete lack of progress I'd made on trying to figure out how to link to a Background model from a Character's view, I decided the best thing to do is to work on some smaller problems until I either ran across a method that seemed like it would work, or INSPIRATO struck me, or I felt like battling that wily Background again.

One of the things I wanted to do is make it so when a user creates a list of Skills, they're displayed in alphabetical order. Sounds simple, right? And it is! Absolutely. But I had only the vaguest idea of how to write such a method (probably finding all the skills, then ordering them by name) and absolutely no idea how to call that method in the view.

So I headed over to Stack Overflow since this seemed like an easy enough problem that I could describe and get answered quickly enough. Who came riding over the hill like Gandalf, ready to save the day? normalocity! I have 0 idea who this guy is, but his method was clear, easy to understand and exactly what I was looking for. Have I mentioned how awesome the Rails community is, both locally and online? One of my favorite things about my learning process has been getting to know more people, and talking to more experienced programmers about Rails, coding and how things work in general.

So here's what I ended up doing. I first had to define the method in my skills_controller (which I had already done, and correctly too!) and then call that method in the view.

So here's the definition I came up with:

def index
  @character = Character.find(params[:character_id])
  @skill = @character.skills.build
  @sorted_skills = @character.skills.find(:all, :order => :name)
end

Not bad! But then I got stuck. How do I call it in the view? Is it a separate thing? I've already got code that iterates over each skill and then spits it back out to the view. So was it a second call? That doesn't seem logical. So what about editing the code I already have, and calling the new method I wrote instead of the previous method?

Just one little change here. We started off with:

<% @character.skills.reject {|skill| skill.new_record? }.each do |skill| %>

And changed it to:

<% @sorted_skills.reject {|skill| skill.new_record? }.each do |skill| %>

So this code is doing the same thing it did before, but instead of simply bringing up @character.skills, it's bringing up @sorted_skills, which has already been defined as @character.skills.find(:all, :order => :name.

And this is just one example. I've got a crazy idea for a way to sort by two variables. For example, a Character will have class and cross-class skills. What about a way to sort these skills both alphabetically and by class or cross class skills? Nutty, I know! I'm letting that one brew for a while, though. Or what about spells? It might make sense to sort spells both by spell level and alphabetically. But you see what I mean? It's kind of getting impossible for me to learn something new in Rails without a) wondering how else I can apply it and b) wondering how I can tweak it, change it, expand it, pose it, scroll it, click it, or zoom it.

It felt really good to figure this out tonight, and even though this one instance is just a tiny fix that literally took two seconds to code, the logic behind it and understanding that logic reaches quite a bit deeper. After all, I'm not learning Rails to build Dungeons and Dragons character databases. I'm learning Rails to understand Rails.

Thursday, August 11, 2011

Adding two columns in a table with Rails

I figured out a way to calculate totals from two different columns in a table, but I'm having trouble extracting that logic and moving it out of my view. In this case, an Initiative's total is the sume of the Dexterity and Miscellaneous modifiers. Here's the code I've got so far:

Initiative Total:
<%= (@initiative.dex + @initiative.misc) %>

Pretty easy, right? But I'd like to just call this something like init_total and call it that way, but I'm not quite sure how to write that code. Also, does it matter if I throw a .to_s on the end of this? I noticed it displays the same either way, but I don't know if a .to_s is strictly required. I'm guessing since this information is already a string, converting it to a string is redundant.

Just a quick update. Feels good to be making daily progress on Manticore, especially since I spent a long time spinning my wheels.

Wednesday, August 10, 2011

Implementing new methods in Rails

I think it's important that every time (or nearly every time) I sit down to code that I try to do something I don't know how to do. I'm making good progress with using the code I've figured out and applying it to other similar things. For example, with my Manticore app I can use the same methods to create Items to also create Special Abilities and Spells.

But what I want is a way to sum totals from different columns in a table, then display that total in the view. I was messing around with the sum and count methods I found in the Rails API, but haven't quite gotten this figured out. The result is a pleasant headache, and that's what I'm going for. I can't just rest on what I know, I need to be stretching my boundaries when I code.

I think the end result will be I'll learn new things faster and be able to work around road blocks more quickly when they DO arise. My ultimate goal isn't simply to build this or that application; I want to understand how Rails applications work, how they go together and how they're built.

Also, I'm going to start blasting out my rails blog posts in Google+ in addition to Twitter, so if you're seeing this twice? Sorry about your luck!

Tuesday, August 9, 2011

If and Unless Methods in Rails

Sometimes shit just works.

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

So I've made some pretty serious progress with Manticore. So far, here's what I've got:

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.

Sunday, July 31, 2011

More Routing Issues in Rails

I've made some progress with Manticore this weekend, but I've hit another wall. Surprise!

Thanks to @unixmonkey and @jqr, I can now add, view and destroy items, linking to the items index page from a menu partial that is called from the character's show page. Success! However, I thought it might be handy to be able to edit items. And that's where my problem comes in. For a while, I was getting a routing error. Then I edited the code and now I'm getting this old chestnut again:

undefined method `item' for #<Character:0x103f0ce50>

What gives? I thought I'd gotten rid of this guy when I defined the character in the items controller.

Here's my edit method from the items controller:

  def edit
   @character = Character.find(params[:character_id])
   @item = @character.item
  end

  def update
    @character = Character.find(params[:character_id])
    @item = @character.statistic
    if @item.update_attributes(params[:item])
      redirect_to character_items_path, :notice => 'Item was successfully updated.'
    else
      render :action => "edit"
    end
  end

And here's how I'm calling it from the partial I created for creating and editing items:

<%= link_to 'Edit', edit_character_item_path(@character, item) %>

Any more tips? I'm pretty sure I'm just not writing this correctly. This code is based on what I've got for my other models (statistics, armor class, etc) but I wonder if it might be different based on a couple of things. For one thing, those other models have a has_one relationship with Character, while Items has a has_many. For another, the has_one models are all displayed in the Character show page, while Items is being created from the Items index page. Am I on the right track here? Any advice as to how to solve this issue?

On a less begging for help note, I've spent a good 5 hours working on Manticore this weekend. I notice when I'm working on a personal project and not a tutorial, I can focus for longer periods of time and I find the work more interesting. When doing a tutorial, I feel like it's a valuable use of my time but it's not an interesting use of my time. Does that make sense? Regardless, I absolutely lose track of time when working on my own projects, even if it's just repeatedly butting my head up against trying to get a goddamn edit method to work.

Saturday, July 30, 2011

Models, forms and view pages in Rails

I'm back to working on Manticore after a couple months away doing tutorials. I've made some progress this afternoon, but now I've run into a snag.

Here's what's going on: I have two models, Character and Item. I've created a form_for new Items that belong to a Character. The form works fine when displayed in the Character view, but what I want to do is move the form and Item listing out of the Character view and into the Index page of Item, so I can link to it from the Character view. I've got a _menu partial that I'll be using to display other views relating to Character, such as Skills, Spells, Items and so on. I'm not sure what the issue is, but simply transplanting the code as is gives me this error:

undefined method 'items' for nil:NilClass

Here's the exact code I'm using:

<h2>Add an item:</h2>

<%= form_for ([@character, @character.items.build]) do |f| %>
  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :type %><br />
    <%= f.text_field :type %>
  </div>
  <div class="field">
    <%= f.label :location %><br />
    <%= f.text_field :location %>
  </div>
  <div class="field">
    <%= f.label :description %><br />
    <%= f.text_area :description %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

<table>
<% @character.items.each do |item| %>
  <tr>
    <td><%= item.name %></td>
    <td><%= item.type %></td>
    <td><%= item.location %></td>
    <td><%= item.description %></td>
  </tr>
  <table>
<% end %>

Like I said, this works just fine in the character/show page, but does not work when placed in item/index and linked to from my _menu partial. Any ideas?

Here's a link to my git repository:

Sunday, July 24, 2011

More Heroku Rails Deployment Issues

I've (partially) fixed my issues with deploying to Heroku. The solution was to specify rake version 0.8.7, as noted all over Stack Overflow for people who had the same error I was getting. I could have fixed this issue earlier, if I'd realized you deploy to Heroku from Git, not from your local machine. So I was updating my code, then trying to migrate the database on Heroku and I kept getting the same error because the code hadn't been changed on Git. Still, progress!

But I'm still having a problem. Take a look at the deployed version of my Depot application:


And here's a screenshot of how it looks on my machine:


Heroku is not displaying the product listing and I can't figure out why. The database information is stored in a seed file, so I thought a heroku rake db:seed command would populate the data and fix my issue, but no such luck. I've also noticed that the new action for my Product model throws an error on Heroku, but it works on my local version. Any ideas what's going on here?

Here's a link to my git repository for this application: