How can I define a relationship between two controllers. I have one controller called rides and another called registrant. Is there anyway I can access the registrant database from within the rides controller? I was thinking
#registrant = Registrant.find(:first)
from within rides, but that didn't work.
Any suggestions?
Thanks
You can access your registrant model from your rides controller just like accessing it from any other controller. What do you mean by Registrant.find(:first) not working?
Now, if there's a relationship (or association as it's normally called) between your rides model and registrant model (like a has_many association), you can use nested resources to nest one controller in another.
Check out the Action Controller Overview and Rails Routing from the Outside In guides and think about picking up a good book on Rails like Agile Web Development with Rails.
If you have defined models: ride and registrant (or more general user) then you can setup a before_filter on the rides controller:
before_filter :get_user
def get_user
#user = User.find(:first, :conditions => %Q(userid = "#{params[:user_id]}"))
end
This would fetch the the user with user_id passed in as a parameter before the controller generates the view.
Yes, that should work. To get the terminology right, you are accessing the Registrant model from the RidesController. They should both be in the same database, but in separate tables.
Please post the error message you are getting.
Related
I am new to rails and I feel this question should have an easy answer but I can't figure it out.
in rails I have two tables USERS and INFOS they have many to many relationship and there is a third table INFOS_USERS but it doesn't have the model.
my problem is I want to add to this association table from Info view, but I have no method to call in the controller!
should I create a new model and controller?
is it possible to add a custom methods to controller?
Thanks
edit: I can write to table from controller but problem is I don't have any controller for the association table so I don't have any method to call from view.
Yes, you can add custom methods (actions) to a controller
Your routes might look like:
resources :users do
members do
get 'infos' # => /users/:id/infos
post 'add_info' # => /users/:id/infos/add_info
end
end
In this case it might make sense to use nested routes, which means you would have a different controller for the 'infos' - checkout the rails guides http://guides.rubyonrails.org/routing.html#nested-resources
for adding #user to #info:
#info.users << #user
if you need create new User from association:
#info.users.build
and you don't need any extra Controllers or Models
I'm in the process of learning Ruby on Rails, and now I have created the mobile version of my application.
I created the relation between models ans controller is one-one. Now I want to make changes to manage three models from one controller. I have read and watch videos a lot about how to do this but, it doesn't work when I try to do it in my application.
Models:
class Subject < ActiveRecord::Base
has_many :pages
class Page < ActiveRecord::Base
belongs_to :subject
has_many :sections
class Section < ActiveRecord::Base
belongs_to :page
Controller:
class SubjectsController < ApplicationController
has_mobile_fu
layout "admin"
before_action :confirm_logged_in
def index
#subjects = Subject.newest_first
#pages = #subjects.pages.sorted
end
This is the error:
NoMethodError (undefined method pages' for # <ActiveRecord::Relation::ActiveRecord_Relation_Subject:0x007fbbf3c9b218>):
app/controllers/subjects_controller.rb:10:inindex'
The application works well if I keep each model managed by its controller. The problem started now that I want to control multiple models from one controller.
Can definitely use multiple models in a single controller. The issue here is you're calling a method that doesnt exist for the active record relation.
An active record relation is typically a collection of returned objects from a query using active record. So the newest_first is returning multiple, not just one. If you want to get all pages for the subjects and sort them, you can do this:
#subjects = Subject.newest_first
#pages = #subjects.map(&:pages).flatten.sort { |a, b| a.title <=> b.title }
Can switch the attribute on which you wish to sort by. The map function goes through each one, and returns the object of which i passed in the symbol. It's a shortcut for:
#subjects.map { |subject| subject.pages }
The flatten then takes that array of active record relations and flattens it into a single array. I then just use the array sort.
Edit Here's a way you can do it using the database:
#subjects = Subject.newest_first
#pages = Page.where.not(:subject_id => nil).order(:title)
MVC
Something else you'll benefit from is to look at the MVC Programming Pattern:
Rails is famous for its strict coherence to the Model-View-Controller pattern, as it works like this:
You send a request to your app
Rails "routes" your request to a specific controller / action
The controller will then collate data from your Models
The controller will then render a view to display this data
The relationship between models and controllers is exclusive; meaning you don't have to call certain models from a controller, etc.
So the basic answer is no, you don't need to call a single model from a controller. However, you do need to ensure you have the correct model associations set up, as per the explanation below:
Associations
The caveat here, is that since Ruby is object-orientated (and Rails, by virtue of being built on Ruby, also being so), it's generally considered best practice to build your application around objects
"Objects" are basically elaborate variables (constructed from your Model classes), but the pattern behind making OOP work properly is super important - everything from Rails' routes to your controller actions are designed to be object-ORIENTATED
Each time you initiate an instance of a Model, Rails is actually building an object for you to use. This object allows you to call / use a series of attributes / methods for the object, allowing you to create the experience you require with Rails
--
The bottom line -
I would highly recommend examining the ActiveRecord Associations in your models (which will determine whether you need to call a single model or not):
#app/controllers/subjects_controller.rb
Class SubjectsController < ApplicationController
def index
#subjects = Subject.newest_first #-> good use of OOP
#posts = # this is where your error occurs (`.posts` is only an attribute of each `Subject` object instance, which is fixed using the accepted answer)
end
end
Hopefully this gives you some more ideas about how to construct Rails applications
Supposing I have 3 tables: Users, Roles and UserRoles. I can fetch the user_roles in the request: users/1/user_roles but what if I want to fetch the roles of a user such as: users/1/roles.
My relation is as follows:
has_many :roles, :through => :user_roles
Is it possible?
The relation in your model has no direct relevance to the url you go to. You need to replicate your existing behaviour for routes rather than user_routes by either adding a new action or new controller and creating new views etc.
At the moment you probably have either:
an action called user_routes in the UsersController
an action called index in the UserRoutesController
So either:
Add an action called routes in the UsersController
Add an controller called RoutesController with an index action.
Regardless to which method you are using, in your action set your instance variable to user.roles instead of user.user_roles.
You can then write whatever view code you need.
Hey I am stuck with my orientation in rails.
I got a User model, a Course Model and a CourseEnrollment Model.
When I want to add a link in my Course Index View like
link_to 'join' CourseEnrollment.create(:course_id => course.id, :user_id => current_user)
Does this create method belong to my Model? I am confused because in my User Model I defined a method that uses role_assignments.create(.....). What is the difference between these 2 create methods? I cant use course_enrollments.create by the way. Thx for your time
I'm a bit confused as to what you're asking, but I'll try my best.
(First of all, in your example, current_user should probably be current_user.id.)
When you call CourseEnrollment.create, you are simply creating a new CourseEntrollment model with the specified attributes.
Assuming that your User model has_many :role_assignments:
When you call #role_assignments.create from within your User model, Rails automatically creates the association for you (e.g. sets the user_id to the id of the user). This doesn't have to be done within the model itself, though:
current_user.role_assignments.create(...) # automatically sets the association
Assuming that your User model also has_many :course_enrollments, the following will create a CourseEnrollment model and automatically associate it with the current user:
current_user.course_enrollments.create(...)
I'm working on a rails app and using a singular resource. However the controller name for the singular resource is plural.
Eg map.resource activity_report expectes the activity_reports_controller.
The explanation given in the rails 3 guide is: "... you might want to use the same controller for a singular route and a plural route..." That is a reasonable explanation, but what is the use case for using the same controller to handle a singular route and a plural route?
In a RESTful Rails application there is usually a mapping of one controller per RESTful resource. For example, let's say we wanted a controller to process user logins (/session) but also to provide a list of users who are currently logged in (/sessions). Logically we could put both of those responsibilities within a SessionsController:
class SessionsController < ApplicationController
# GET /sessions
# Display a list of logged in users
def index
...
end
# GET /session/new
# Display the login form
def new
...
end
# POST /session
# Authenticate a user
def create
...
end
end
An alternative would be to split the functionality for listing logged in users out into a separate administration controller.
You can use it.
class UsersController < Application
end
map.resource :user
map.resources :users
Another situation in which I can imagine using it would be, let's say (and this isn't necessarily the business model you'd want, but stay with me for a moment) you are going to make a site of film reviews, and film information. So, on the one hand you'd have the link to your list of the latest reviews be a plural resource route, something like this:
http://yoursite.com/reviews?count=5
So, in this case, you have a controller for the collection, right? But you're only going to review each movie once. So what if you wanted to provide an easy access to a movie's review?
http://yoursite.com/movies/pirates_of_the_carribean_2/review
Well, there's a nested single resource route, because a movie has_one review, right?