Reputation: 125
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
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
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
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