Writing Basic Models

Unlike controllers and views, there’s no default superclass that models inherit from; they’re just plain-old Ruby objects. We can use the standard attr_accessor, reader, and writer functions to declare getter and setter methods, which sometimes are all you need.

Many apps have users and profiles, so let’s work through a portion of that sort of app and use some nice models. Let’s create a new project (such as motion create UserProfile) and two subdirectories within ./app: models and controllers. We’re not only going to cover models; we’re going to keep building on what we already know.

Our app will let us create, view, and edit users. Since we’re doing an awful lot of work with users, this sounds like a good place to begin with our first model. To get started, we first create user.rb in ./app/models. For now, each user will have a name, email, and ID. This is a pretty basic implementation of User:

 class​ User
 attr_accessor​ ​:id
 attr_accessor​ ​:name
 attr_accessor​ ​:email
 end

That’s all we need for now. Let’s add our first controller, which we can use to view a user. Create user_controller.rb in app/controllers, which will be a subclass of UIViewController. We’ll use a custom initializer that takes a User and fills the UI appropriately. Sound good? Let’s start with that initializer.

 class​ UserController < UIViewController
 attr_accessor​ ​:user
 
 def​ initWithUser(user)
  initWithNibName(​nil​, bundle​:nil​)
  self.user = user
  self.edgesForExtendedLayout = UIRectEdgeNone
  self
 end

Pretty typical initializer, isn’t it? We’re going to assume the user passed is a User object, but we’ll worry about that later. Next, we need to set up the view. This will be kind of lengthy, but that’s nothing new for us at this point.

For each of our User properties, we’ll create two labels: one to tell us what value we’re looking at (“Email”) and one right beside it that presents the value of that property for our user (“[email protected]”). Since we are using Ruby’s nifty send, we can do this in one loop.

 def​ viewDidLoad
 super
 
  self.view.backgroundColor = UIColor.whiteColor
 
  last_label = ​nil
  [​"id"​, ​"name"​, ​"email"​].each ​do​ |prop|
  label = UILabel.alloc.initWithFrame(CGRectZero)
  label.text = ​"​​#{​prop.capitalize​}​​:"
 
  label.sizeToFit
 if​ last_label
  label.frame = [
  [last_label.frame.origin.x,
  last_label.frame.origin.y + last_label.frame.size.height],
  label.frame.size]
 else
  label.frame = [[10, 10], label.frame.size]
 end
  last_label = label
 
  self.view.addSubview(label)
 
  value = UILabel.alloc.initWithFrame(CGRectZero)
  value.text = self.user.send(prop)
  value.sizeToFit
  value.frame = [
  [label.frame.origin.x + label.frame.size.width + 10, label.frame.origin.y],
  value.frame.size]
  self.view.addSubview(value)
 end
  self.title = self.user.name
 end
 end

Don’t get overwhelmed! We just created two UILabels for each property and laid them out nicely.

Before we run our app, we need to set up our AppDelegate to get the controller on the screen. First, we create a new User in app_delegate.rb and use it to initialize a UserController. We’re going to wrap it in a UINavigationController so we get the nice effect with self.title.

 class​ AppDelegate
 def​ application(application, didFinishLaunchingWithOptions​:launchOptions​)
  @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
 
  @user = User.new
  @user.id = ​"123"
  @user.name = ​"Clay"
  @user.email = ​"[email protected]"
  @user_controller = UserController.alloc.initWithUser(@user)
  @nav_controller =
  UINavigationController.alloc.initWithRootViewController(@user_controller)
  @window.rootViewController = @nav_controller
  @window.makeKeyAndVisible
 true
 end
 end

Let’s give it a rake and see what happens! Your app should look something like Figure 7, A controller for our User model. Our view isn’t the prettiest, but a good designer could dress up even this limited information into something shippable.

images/models/first_user.png

Figure 7. A controller for our User model

This is great, but this User class didn’t help out all that much. We’re going to give it some abilities that will make our code much more flexible while showing off what smart models can do.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset