user2472480
user2472480

Reputation: 125

The MVC model and methods

I'm trying to wrap my head around the MVC model, so I'm wondering how to implement something in it.

I have a resource that has different properties. I also have a controller from it that I set up from scaffolding, like new, show etc.

The way I understand it is that I am supposed to define in the controller what things are available for my view to use. Going from that, what I want to do is make a method and use it in the show view.

I want to make a .find method that checks all the values of a particular property of my resource, e.g. I have a resources named users with a property of region. When I view a users profile page I want an area to list all users in the same region as the current profile.

Where do I define this method? Is it in the controller or the model, and then how do I call it properly in the view? Currently there is already code in the show method in the controller, and, if I'm correct, I understand that the last line of the code executes, or prints out in the view, so how do I include that in it? Wouldn't it conflict?

I'm sure I'm not understanding something but I would just like some guidance.

Upvotes: 0

Views: 141

Answers (3)

saneshark
saneshark

Reputation: 1243

Sibevans answer is the best way to handle this if you are working with associations, but if you're working with an existing table and region happens to be an attribute of your User model which I suspect is the case, I would suggest building your find method within the user model as an instance method, preferably with a descriptive method name that explains what it is doing. You can later create an alias to that instance method if you prefer:

class User < ActiveRecord::Base

  def find_all_users_belonging_to_same_region
    User.where(:region => self.region)
  end

  alias :find_region :find_all_users_belonging_to_same_region

end

Note this returns an ActiveRecord Relation and not an array. If you prefer an array you could put a .all on the end like this:

User.where(:region => self.region).all which is the equivalent of

User.find_all_by_region(self.region)

That being said, there are benefits to using an ActiveRecord Relation in that you could later chain additional database methods on that method, such as

my_user.find_all_users_belonging_to_same_region.where("income > ?", 50000)

Note, since find is a reserved word in ActiveRecord, I would advise not using it as the name of your method if it is to go in the model.

Then from within your controller, you could define an action called find, which works on the instance of the user you have by way of params.

get users/71/find

would pass the user id 71 to the params hash in your controller and you can access your method on that object as follows:

def find
  @user = User.find_by_id(params[:id])
  @users_in_region = @user.find_all_users_belonging_to_same_region
end

And those two instance variables you just created in your controller, one being your current user, and the second being your array or ActiveRecord Relation of users belonging to the region would all be available objects to use in your view.

Upvotes: 0

Sibevin Wang
Sibevin Wang

Reputation: 4538

As Donovan mentioned in the comment, you may need two models - User and Region and an association between them to handle their queries, here is an example:

First of all, your users table need a region_id column to associate the region where the user belongs to.

db/migrates/20131227153435_create_users.rb

class CreateUsers < ActiveRecord::Migration
  def change
    create_table(:users) do |t|
      t.belongs_to :region
      # ...
    end
  end
end

And add associations in your User and Region models.

app/models/user.rb

class User < ActiveRecord::Base
  belongs_to :region
  # ...
end

app/models/region.rb

class Region < ActiveRecord::Base
  has_many :users
  # ...
end

Then you can get what you want in your controllers.

user = User.find(1) # find the user with id = 1
user.region # to get the user's region

region = Region.find(1) # find the region with id = 1
region.users # to get all users who are in this region

Please reference Rails Guides Guidelines - Active Record Associations to get more details.

Upvotes: 2

tuxdna
tuxdna

Reputation: 8487

Assuming you have a resource named resourceone.

The logic for fetching the data from database ( via a model ) will go to this file:

app/controllers/resourceone_controller.rb

This would look something like this

class ResourceoneController < ApplicationController
  def index
    @resourceones = Resourceone.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @resourceones }
    end
  end
end

Now your view will be in this file:

app/views/resourceone/index.html.erb

This is where you can write your HTML and embed some ruby code in erb tags.

Now in your case you need to make a relationship between your resource and a user. So once you do that, in the controller, you can do:

@user = User.find(user_id)
@resourceones = Resourceone.where(user: @user)

All the instance variables like @user and @resourceones are automatically available in the views, so you can just use them to render the UI.

For any more specific API, you may want to visit http://guides.rubyonrails.org

Upvotes: 0

Related Questions