Showing posts with label methods. Show all posts
Showing posts with label methods. Show all posts

Wednesday, December 21, 2011

Working with the Method method in Ruby

So with the help of my friend Z (also known as Chris to some, mostly just his wife) I've made some progress on Dungeon Crawler. But not much.

Namely, he showed me how to abstract my routing, so rather than having

get "/torch_room" do
  @torch_room = torch_room
  erb :torch_room
end


I have a method that automatically builds a route based on methods that already exist for rooms. Pretty awesome! I think learning to be less specific and abstracting my code is one of the most difficult things I'm learning. One of the guiding tenets of Ruby is DRY (Don't Repeat Yourself) and I really just need to be aware when I'm writing the same basic code more than once that it can probably be abstracted.

Ok, but here's my problem. I still can't figure out a way to collect input from a form, pass that input into an instance variable so that I can check it from other rooms and perform redirects based on the input itself. Does that make sense? I am absolutely trying my hardest to be clear about what I'm trying to do. Z also clued me in on a Method method but I can't figure that out, either.

Here's a gist with what I've done so far, but (FAIR WARNING) it's straight up busted:

Busted Gist

That said, I've noticed a funny thing about this problem. Bear in mind I've been wrestling with this guy off and on since my last post. (I DID do a couple of fun tutorials in between wrestling matches, mostly to keep myself limbered up) I didn't get frustrated in the usual "FUCK IT I GIVE UP" kind of way, but more in a "huh that didn't work. Ok let's try another thing. Hmm nope, that didn't work either," kind of way.

I did try some CRAZY other things, based on what my friend Miles told me about last time I posted about this problem (said crazy things mostly involved working with hashes, trying to convert hashes to strings, etc. Does that work? PROBABLY, I DON'T KNOW!) with minimal success.

I think this is how Daniel-san felt when he realized the entire time he thought he was washing Mr. Miyagi's car, he was actually learning karate.

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, 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.

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.