Retrieve the controller name from a class name - ruby-on-rails

I am using Ruby on Rails 3.0.7 and I would like to retrieve a controller name given a class name. That is, I have
Articles::Category
and I would like to retrieve
articles/categories
I would like to retrieve the controller name inside a view file not related to the Articles::Categories controller.
How can I do that (possibly using some Ruby on Rails core method)?

Articles::Category.name.underscore.pluralize
=> "articles/categories"
As mentioned by many others, there is no special method for that. But as long as you followed Rails conventions, this approach will take you far.

To get the controller name, say inside your view, you can do :
<%= controller.controller_name %>
To get the name of a class, say User, if you have a user object named user :
user.class.to_s
Other than that, i don't think there's a correlation between a controller and a model, that can give you the controller name from a class name, because they are different things. You can maybe create a hash like {:controller => 'class_name'} and map those yourself.

Articles::Categories.name.underscore #=> articles/categories
And it underscores camelcased words to so that:
RailsAdmin::ApplicationHelper.name.underscore #=> rails_admin/application_helper

Assuming that you really meant Articles::CategoriesController then Articles::CategoriesController.controller_path will give you what you want.
Update The question is, given the name of a Rails Model, how do you get the name of the associated controller?
The answer to that question is, you can't. There is not a one-to-one mapping from the model name to the controller name. The User model could be controlled by the users_controller.rb and/or admin/users_controller.rb or not have an associated controller at all. You can certainly guess at some likely possibilities based on Rails conventions but you can't know.

Instead of underscore.pluralize just use tableize:
ActiveRecord::Base.name.tableize
=> "active_record/bases"

Related

Rails4 Access controller_name from model method

I have user role based access control. User has many roles.
Each role has access to some controllers, actions and scopes.
I have method can_control?(controller) in User model which check if user have access to specific controller. I have similar method to actions.
Then in view or controller I can make simple logic to hide some information or permit access using:
current_user.can_control?(controller_name)
I wonder if it possible to create method in User model which automatically takes controller_name. I tried to define method in model.
def can_control?
self.permitted_cotrollers.include?(controller_name)
end
But it gives me an error:
undefined local variable or method `controller_name' for #<User:0x007f00e8ceb928>
I understand error, but can find solution or if it possible to have one.
Here is the best solution I can think of : You can access the current controller name in params[:controller] from any controller method.
In User model :
def can_control?(params)
self.permitted_controllers.include?(params[:controller])
end
In any controller :
current_user.can_control?(params)
In your model, you can get the standard associated controller name by using :
"#{self.class.to_s}Controller"
self refers to your model
.class gets its class
.to_s converts its class to a string containing its class name
If you need it written in snake_case instead of CamelCase, use this :
"#{self.class.to_s.tableize}_controller"
.tableize converts the CamelCase name of your model into the snake_case name used in your controller

Convert an instance to another type of instance

In ASP.NET, when I want to send a list of model instances to view layer, I convert them into another type (ModelView) by the following code:
var userViewModels = users.select(new {
Name = Name,
UserName = Username
});
I do this because I don't want to send all of my user model data (like password) to view layer. I put this code in my business logic Layer.
I'm using AJAX, and I'm sending my data by JSON protocol. What is the best practice in Ruby on Rails to do a similar action?
In RoR you simply pass models to your views.
Also, view in RoR can directly access (though it's not recommended) models from database. So "hiding" models does not make sense here.
You can consider rails generated scaffold as a close to the best practices.
Controller is used for selecting models from database
View is used for rendering model to the user
Model is the main place to store business logic
Although it is probably unnecessary, as dimakura pointed out, you can select arbitrary attributes when finding by using the select method. Your example would end up looking something like:
#users = User.select(:name, :username)

MVC 4 Creating Model With Data Passed from View to Controller

I'm new to MVC and I have a relatively basic question. I've found some answers through searching, but nothing that conclusively makes me feel like I know the 'best practice' for this common functionality:
I have strongly typed views and I have a relationship between 'Members' and 'Pets'. I want a page on my Member edit view to 'Create a new Pet'.
At this point, I'd like to pass the memberId from the Member edit view to the Pet create page so it can start a new instance of the Pet model with the correct member associated.
I'm thinking the best practice is to pass the memberId from the Member edit view (but by what method?) and then store this value in a hidden form field that is the correct name for the strongly typed 'memberId' value on the Pet model. Then, the Pet create controller should automatically pull this value when it's creating the Pet.
I need help passing the memberId from the Member edit view to the Pet edit view, and also general thoughts if this is the best way to accomplish what I'm looking to do. Thank you for your time and assistance!
The straightforward way is to pass the memberId as a route value to the CreatePet Action.
So your Member View might have a Url like the following to navigate to the CreatePet Action:
#Url.Action("CreatePet", "PetController", new { memberId = Model.MemberId })
And the CreatePet action would have the memberId as a parameter
public ActionResult CreatePet(int memberId)
{
...
}
UPDATE
From comment to question:
I was also curious if I could just pass the entire Member model in the 'Add a Pet' button and use that in the Pet Controller? This might be the preferable method
This doesn't sound like a good idea for a number of reasons. Why should the Pet need to know so much about the Member? And what if the client spoofs the Member values - you shouldn't rely on them, so would be better off looking up the Member server side using only the id that is passed as a route value.
So the way that is really preferred that I have seen for handling this kind of problem is the use of the MVVM pattern where you create a ViewModel object specifically designed for the view. While this may seem like, I have so many Views! But thats probably when you need to switch to dynamic views. However if you can not this pattern is a good one to follow for it. For instance you need a member id and the pet information I believe? What you can do is pass down an object that contains the list of pets, or something like that. Then in the view model you also pass down a list of member ids or the member id. I am not quite clear on the point of the application. But bottom line is you create a model that is specific to that view that also makes use of the actual models in order to pass down the necessary information. This links is a good description of it.
http://msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx
Good luck.

Relationship between model and controller in rails

i am a beginner, i got doubt regarding model and controller name specification i have created model name as "login" weather the controller name should plural of model name like "logins" ?
You might want to read up on naming conventions.
The Model is usually singular and the Controller is usually plural.

In Ruby on Rails, what is a good way to get subclass's name in a base controller class?

If both ProductsController and CategoriesController both inherit from GenericController, what is a good way to get the string products in the base class when the URL is pointing to the Products controller? (in this case, the base class's index action is doing things that would need to use the string products to query the database)
self.class.to_s can be used, and it is Analytics::ProductsController, or params[:controller] can be used and it is analytics/products, so both can be used to extract the sub-class's name. Is using one better than the other, or is a third way even better?
Try
controller_name
Refer to the documentation for more details.

Resources