Ruby on Rails: When to add a new resource - ruby-on-rails

I have two questions on how the MVC works. I'm pretty sure I should add several resources, but I'm just coming to this conclusion and wanted to ask first to get a better understanding.
First question:
I have two models, user and subject. Users can enter subjects into the database. For each subject there are 5 data entry forms (Baseline, 3month, 6month,...) that are about 100-200 questions each (The relationship would be each subject has 1 of each data entry form). Should each data entry form be a new resource?
Second Question:
Lets say I want to randomize a few subjects into a group:
From the view, the user enters the amount of subjects to be randomized into a group, as well as the group name to be assigned. The form tag specifies an action I created, just for this function, called randomize.
From the controller, randomize uses the params sent from the view to query the database, and then to update each record to reflect the group. Instead of creating a new action for the randomize function, should I create a new resource for it? And as a side note, should any of these calculations be done in the model (other than defining the variables)?
Thank you for your time. Any help would be greatly appreciated. I am officially over-whelmed by all of the information I'm learning about this...but I feel that I'm really close to actually understanding the MVC.

I'll answer your second question first.
You should be creating controllers to handle CRUD tasks for resources. In this question you ask about creating a "Group". Regardless of whether this is an actual resource, or just a modification to a collection of other resources, you have the concept of creating a "Group", probably reading/updating a "group" and certainly deleting one.
Based on this, I would rather have a RandomGroup controller which I can call using a standard REST interface, rather than some #randomize action stuffed in the side of another controller.
As for your first question ... maybe, maybe not.
It really depends on whether an data entry form has any business logic of its own. If it doesn't then there's no harm it being part of a large object. But if your tests and code start to become too complex within the Subject model you may want to split it out into multiple models or at least multiple modules included into that model.
Perhaps you could consider that "Baseline", "3month", "6month" are all the same ... aside from their lead time. Perhaps that is a model in itself, and Subject could has_many :forms ??
Food for thought.

Related

Rails MVC - Should database search logic go in the model or the controller

I would like to make sure my code is properly organized/designed according to the following paradigms/patterns:
- Model View Controller
- Rails Convention over Configuration
- Skinny Controller, Fat Model
I have listed them here in the order I think is most important.
My issue
After reading several articles, in particular this one and this one too, I started to move some of the logic in my controllers, to my models.
However, I can't decide whether or not to move my searching logic (explained in depth, later) from the controller to the model, even after reading more posts/articles like these: MVC Thinking, and Model vs. Controller, Separating concerns and many more not listed here.
The scenario
View
Two pages:
1 page contains a text field and submit button which sends the user's input as an argument in params in a POST request to the second page.
The second page simply renders each neatObject in a given array, let's call it #coolList.
Controller
A method, let's call it awesomeSearch, is invoked when the second page receives a POST request. (Thanks to Rails Routing)
awesomeSearch should take the user's input, available as params[:searchString], and work with the NeatObject model to build the #coolList and make that list available for the view to render.
Model
The NeatObject model handles requests from controllers and returns neatObjects back to those controllers.
The NeatObject model defines the relationship between neatObjects and other tables in our database.
Database
These are the attributes that make up each neatObject according to our database:
id - int
description - string
address - string
date_created - timestamp
What's Missing?
How the controller works with the model to get matches for the user's input.
This is the part I am confused about. The logic itself is very simple, but I am not sure which pieces belong in the model, and which pieces belong in the controller.
Should the controller pass the search string to the model, and the model pass back the results?
Should the controller ask the model for all of the neatObjects, then only keep the ones that match?
Is the solution a little of both?
To be able to ask questions about specific bits of the logic, I'll next outline the search process with more detail.
The search logic in depth
The process involves finding neatObjects that match the search string. It would be impossible to move on without defining what we consider matches for neatObjects. To keep things very simple, we will say that:
A neatObject matches a search string if the search string is contained within its description or its address, ignoring case and leading/trailing whitespace.
This definition is not guaranteed to be permanent. There are several things that may change our definition. We may need to test against more attributes than just address and description, perhaps if the database guys add a new important attribute, or the UI guys decide users should be able to search by ID. And of course, the opposite of these scenarios would mean we need to remove an attribute from the list of attributes we are testing. There are many situations that could change our definition of a match. We could even have to add or remove logic, perhaps if it is decided that we should only test the first word in the description attribute, or perhaps if we should no longer ignore case.
Now we know what defines a match and we know that our definition may change. Now we can more concretely define the search process.
Here is an outline of the steps:
Get a reference to all neatObjects
Loop through each neatObject, putting each individual one through the match test
Test passes - add/keep neatObject in results list
Test fails - do not keep neatObject for results
Make results available to the view
I will reference these steps as I show possible implementations.
Implementation
The search functionality can easily be implemented in either the NeatObject model, or the controller serving the view.
Normally, I would just write all of the logic in the controller, but after I learned about the "Skinny controller, Fat model" design, I thought it definitely applied in this situation. This article in particular made me think to reorganize my code, after I saw the author had implemented a "search-like" function in the model. The author's function did not handle user input though, so I was wondering how it should be handled.
This is how I would have written the code before learning about "SCFM":
Search logic in controller:
#searches_controller.rb
#This is the method invoked when second page receives POST request
def search
#neatObjects = NeatObjects.all.to_a
#neatObjects.delete_if {
|neatObject| !matches?(neatObject, params[:searchString])
}
end
def matches?(neatObject, searchString)
if((neatObject.description.downcase.include? searchString.downcase) ||
(neatObject.address.downcase.include? searchString.downcase))
return true
end
return false
end
This method gets its reference to all of the neatObjects (Step 1) by calling .all() on the NeatObject model. It uses the array function delete_if to perform the match test on each neatObject, and only keeps those that pass (Step 2). Step 3 is accomplished automatically automatically since we store our results in an instance variable in the controller which serves the view.
Placing the logic in the controller is very straight-forward, but when considering the "SCFM" design pattern, it seems very illogical.
I've written another option, in which the controller sends the user's input to a function in the model, which will return the the neatObjects which match the input.
Search logic in Model
#NeatObject.rb
def self.get_matches_for(searchString)
all.to_a.delete_if { |neighborhood| !matches?(searchString, neighborhood) }
end
def self.matches?(phrase, neighborhood)
fields = [neighborhood.name, neighborhood.address]
fields.map!(&:downcase)
phrase.downcase!
fields.each do |field|
if (
(phrase.include? field) ||
(field.include? phrase)
)
return true
end
end
return false
end
This method gets the complete list of neatObjects with all() (Step 1). Just like the first method, the model method uses delete_if to remove array elements (neatObjects) that don't meet a certain criteria (passing the match test) (Step 2). In this method, the controller serving the view would call get_matches_for on the NeatObject model, and store the results in an instance variable (Step 3), like this: #neatObjects = NeatObject.get_matches_for( params[:searchString] )
I do think that the model option is cleaner, and slightly more maintanable, but I'll go more in depth in the following section.
Concerns
I can see pros and cons to both the model method and the controller method, but there are things that I'm still unsure about.
When I read over that article I've referenced several times (just like I did here), it was very logical that the model defined a function to return the recently added people.
The controller didn't have to implement the logic to determine if a person had been recently added. It makes sense that the controller shouldn't, because that is dependent on the data itself. There might be a completely different implementation of the "recency" test for messages. The recent people might include people added this week, while recent messages are only those messages sent today.
A controller should just be able to say People.find_recent or Message.find_recent and know it got the correct results.
Is it correct to say the find_recent method could also be modified to take in a time symbol, and return objects for different time periods? Ex - People.find_in_time( :before_this_month ) or Messages.find_in_time( :last_year ). Does that still follow the MVC pattern and Rails convention?
Should a controller be able to find matches for user input with NeatObject.get_matches_for( searchString )?'
I think the matching logic belongs in the model, because there are certain/specific attributes that are used in testing, and those attributes are different depending on the data. We might have different attributes for different tables, and those attributes definitely shouldn't be defined by the controller. I know the controller depends on the model, not the other way around, so the model must define those attributes, even if the rest of the logic is in the controller.
And if the model defines the attributes that are used when searching, why shouldn't it define the entire search function?
The above text explains why I think the model should handle the searching logic and expresses the majority of my questions/concerns, however I do have some opinions favoring the other option.
If the model is concerned only with the data, how can one justify passing user input to it?
If the controller doesn't handle the search logic, it still needs to send the user's input to the model. Does it clean it up before it sends it? (Removing leading/trailing whitespace and downcasing the string.) Does it just send the exact input it got from the user?
Where is the testing done to make sure the input is not malicious?
Some of my biggest questions:
Does the answer for where the logic goes change for each case?
If the search/matching process was simpler, would the code's place change? For example, if the searching was simpler:
If the only attribute being tested was the address and that was unlikely to change, would we just handle the search with the controller?
If we were making an advanced search feature, where the user decided which attributes to include in the search and also controlled some other factors, there would be a lot of user input just to define the arguments to the search function. Would that be too much logic or user input to place in the model?
In conclusion
How can I always be sure that I am putting logic in the right place (MVC)?
For my specific case, with this data and this search/match process, how should I organize the code?
What guidelines can be followed when you find a gray area, or are unsure about where logic belongs?
This is something that varies a lot between cases (each application is different) but here's what I do on my end (large sports app that searches lots of tables from many different places):
start by performing small searches with non-repeating code patterns in the controller (or rarely view)
when it turns out the code is needed in more than one or two action/view I move it to the models
I also move the code to the model when the query complexity goes above the average .find or simple .where
Like this, you don't spam your model with one-time-use methods, and at the same time don't repeat the same code over multiple controllers/actions/views
As many thinks in IT and in life, It depends of the scale and the goal.
Considerations:
1) For design: If you see you are violating DRY in your controllers many times, its probably time to move your logic to models.
2) For performance: Since controllers are loaded more than models, Logic in controller tend to performs worst.
And not less important: Unless you are doing something very trivial, and you db has a few thousands rows, do NOT use db for text search. Instead, use a search engine like Solr, ElasticSearch, Sphinx, etc.

has_many :through model names, controller and attributes best practices?

Disclaimer: I really spent time thinking about names of models and variables. If you also do, this question is for you.
I have a Rails project which contains two models: User and Project.
They are connected by the model ProjectsUser, which is a connection model in a many-to-many relationship. This model also holds the role of a user in the given project, along with other attributes such as tier and departments. So this is a has_many :through relationship.
Given this scenario, here is everything that always bothered me on all my rails projects since I started developing on it:
Should I use a ProjectsUserController or better add the relevant actions on UserController and ProjectController? At some point, I want to assign users to a project, or even changing the role of a user in a given project. Is it a better practice to leave those actions on the connection controller, or use the model controllers?
Should I write a method to get the role of a user for a given project? This is basically if I should have a method User#role_for(project) or not. Since this method basically is getting the information from the projects_user object it could make more sense to always let this explicity on the code, since most of the times I'll have the project and the user, but not the projects_user. Is this line of thinking correct, or maybe the problem is that I'm should have more project_user on my code than I really do? Are there good caveats for this?
Should I try to rename my table to a non-standard name if it is not obvious? Ok, I got that if I have the models User and NewsSite I should use has_many :subscriptions, but the thing is that naming those models in real life cases are usually harder, by my experience. When the name ends up not being that obvious (for exemple, in my case, maybe project_participation as #wonderingtomato suggested) is for the best, or in those cases it is better to fall back to the ProjectsUser approach?
One extra cookie for pointing beautiful open source Rails code, or by book indications that might help with my kind of questions.
I would use a specific controller. Even if now the interaction sounds simple, you can't know if in the future you'll need to add more advanced features.
I've been handling these kind of relationships in several projects, and using a controller for the join model has always paid off.
You can structure it this way, for example:
index should expect a params[:project_id], so that you can display only the index of users for a specific project.
create is where you add new users, that is where you create new join models.
update is to modify a value on an existing join model, for example when you want to update the role of a user in a project.
destroy is where you remove users from the project, that is where you delete the corresponding join models.
You might not need a show and edit actions, if you decide to manage everything in the index view.
Also, I'd suggest to choose a different name. Rails relies heavily on naming conventions, and projects_users is the default name for the join_table you would use with a has_and_belongs_to_many association. In theory you can use it for an independent model (and a has_many through:), but it's not immediately clear and you might break something. In addiction, it will confuse the hell out of any new programmer that could join the project in the future (personal experience).
What about calling the model something like project_participation?
If you haven't built a lot of functionality yet, and don't have yet that table in production, changing it now will save you a lot of headaches in the future.
update
1) I stand by what I said earlier: your join model is a full fledged record, it holds state, can be fetched, modified (by the user) and destroyed.
A dedicated controller is the way to go. Also, this controller should handle all the operations that modify the join model, that is that alter its properties.
2) You can define User#role_for(project), just remember that it should properly handle the situation where the user is not participating to the project.
You can also make it explicit with something like:
#user.project_participations.where(project_id: #project.id).first.try(:role)
# or...
ProjectParticipation.find_by(project_id: #project.id, user_id: #user.id).try(:role)
But I'd say that encapsulating this logic in a method (on one of the two models) would be better.
3) You are already using a non standard name for your table. What I mean is that it's the default name for a different kind of association (has_and_belongs_to_many), not the one you are using (has_many through:).
Ask yourself this: is the table backing an actual model? If yes, that model represents something in the real world, and thus should have an appropriate name. If, on the other hand, the table is not backing a model (e.g. it's a join table), then you should combine the names of the tables (models) it's joining.
In my mind, REST doesn't always have to map directly to DB records. A conceptual resource here is the association of Projects to Users. Implementation would be different depending on your persistence layer, but a RESTful API would be standard.
Convention over Configuration in Rails is a great helper, but it isn't necessarily applicable to every case 100% of the way through the stack. There doesn't need to be a 1-to-1 mapping between controllers, models, and their respective names. At the app-level, particularly, I want my routes/controllers to represent the public view of the API, not the internal implementation details of the persistence and domain layers.
You might have a UserProjectsController which you can perform CRUD on to add/remove project associations to users, and it will do the appropriate record manipulation without being overly bound to the DB implementation. Note the naming, where the route might be /user/:id/projects, so it's clear you are manipulating not Users or Projects, but their associations.
I think thinking about this sort of thing (both before and after the fact) is what leads to better designs.
I too start with the model and think about the application structurally. The next step in my oppinion is to build the user interface to make sense based on what makes it easy and useful for the user (spending more effort on things that matter more). So if it makes sense for the user to separately edit the ProjectsUser objects then the ProjectsUsersController is the way to go. More likely editing the join model objects as part of the Project (or User depending on the structure of you app) will be a better fit for the user. In that case using a nested form and editing via the controller (and model) that's the main model referenced by the form is better. The controller really lives to serve the UI, so decisions about it should be dependent on the UI.
Yes, if it makes your code simpler or more readable. If you use role more than once I suspect it will.
I would actually name that model something like Member, or ProjectMember (or Membership). It defines a relationship between a user and a project, so its name should reflect what relationship that is. In the occasions where such a name is too unwieldly or too hard to define then falling back to something like ProjectUser is reasonable (but not ProjectsUser). But I definitely like finding a more meaningful name when possible.

Should sorting logic be placed in the model, the view, or the controller? [closed]

Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I have a drop down list that displays values from a table to the end user. I would like to have these values be sorted alphabetically.
According to proper MVC design, at what layer should I place my sorting logic: the model, the view, or the controller?
EDIT: In response to LarsH's question, "Do you mean code that determines what sort order is desired? or code that performs the sort?", I was originally referring to the code that determines what sort order is desired.
Who controls the sort order?
(From Wikipedia)
1) Natural order within the data itself:
The order is part of the Model, so it should go there. A raw pull of "all data" would return the data in the sorted order, and there is no interface to choose the sort order.
2) The user should control how they see the data:
The View would provide an interface (such as ascending/descending arrows) that interact with the Controller, and the Model understands the data well enough to do the requested sort on the data. However, a raw pull of the data doesn't necessarily have to be sorted, unlike in (1).
In either case,
The View doesn't understand that there's a sort going on, other that the ability to show which sort direction has been chosen. Don't put the logic there.
Small caveat
The sorting functionality could go purely in the View, under one circumstance (that I can think of offhand; there may be more):
A "dumb" sort where all the data is already in the view and it doesn't have to use any domain knowledge to do the sort. Very simple string or number comparison, for example. This is not possible in, for example, search results on a webpage when results are likely to be split across multiple pages.
(Note: this quote and citation is taken from #dasblinkenlight's answer, but we disagree on our interpretation of it. read his post and make up your own mind).
According to MVC description,
A controller can send commands to its associated view to change the view's presentation of the model (for example, by scrolling through a document). It can send commands to the model to update the model's state (e.g. editing a document).
Sorting logic (e.g., the sorting comparator/sorting algorithm) belongs in the model since it contains business rules and state data. Since altering the way the model data is sorted falls squarely into the "change the view's presentation of the model" category, the controller is responsible for "doing the sorting" by calling the model.changeSortedState() method.
According to MVC description,
A controller can send commands to its associated view to change the view's presentation of the model (for example, by scrolling through a document). It can send commands to the model to update the model's state (e.g. editing a document).
According to this, sorting logic belongs in the controller, because altering the way the model data is sorted falls squarely into the "change the view's presentation of the model" category.
EDIT: To clarify multiple misunderstandings voiced in the comments, the "sorting logic" is not the code that performs the sort; it is the code that defines the sort. The sorting logic compares individual items to each other to establish an order (e.g through an instance of IComparator<T>) or contains logic that constructs an object to be used for ordering by an external system (e.g. through an instance of IOrderedQueryable<T>). This logic belongs in your controller, because it needs knowledge related to the "business" side of your application. It is entirely sufficient to perform the sort, but it is separate from the code that actually performs it. The code that sorts may be in your view, in your model, or even in the persistence layer that backs your model (e.g. your SQL database).
None of the above. Sorting is business logic, and business logic doesn't belong in any of the three. Not every piece of code in your application will be a model, view, or controller.
What I generally do in my MVC apps is I have a service layer that performs all the business logic. The methods in the service layer should have a clean, simple API with well named parameters. You can then invoke those methods from your controller to manipulate the data in the models.
In that sense, the sorting is "in the controller", but the code itself that does the sorting should not be implemented in the controller, only invoked from there.
Definetly not the controller: It sends messages to view and model but should do as little work as possible. If the user can change the sorting that request gets handled by the controller by informing the model or the view about it.
Maybe the View if it is a pure View thing. If the Application works just as well without sorting then the sorting is just part of the representation and should go in the view.
If the ordering is inherent part of the domain it should go in the model.
Views are the part of MVC which is supposed to contain presentation logic.
Model layer is where business logic is contained.
Controllers only change the state of both, based on user input.
So the choice is - do you think that this is part of the domain business logic or presentation logic.
If you were implementing a proper MVC Model2 or classical MVC pattern, then I would say that the ordering of data provided by the model layer should be triggered by the view's request to the model layer. View asks for ordered data, model layer provides it.
But, since you are using ASP.NET MVC's interpretation of MVC pattern, which is a bit different then your standard MVC - the ViewModel instance should request ordered information from the model layer (for some reason ASP.NET framework thinks that templates should be called "views" and views should be called "viewmodels" .. it's strange).
I would usually do it in the controller to remain in line with the pattern as per the other answers. See below for reasoning.
I've been mulling this over and reading the answers and related material and pragmatically speaking I would say it would depend on your application for instance:
Is it a medium/large application and/or has multiple UI's associated with it (i.e. a Windows App, Web interface and Phone interface).
In this case I would probably construct a service layer and put it in
the business object and then call the appropriate method from the
controller.
If its a well defined single UI website and you're using something like EF Code First and you do not have or have no intention of creating a service layer and plan on using a simple out of the box Extension method to acheive it:
In this case I'd probably put it in the controller as pragmatically
its the best fit with regard to time/budget.
If its the same as the above BUT cannot be implemented with an out of the box extension method.
I may well choose to pop it in the Model class (if its truely bespoke
to that single type) as it would be more appropriate here than in a
controller. If the sort could be applied to more than one class then
I'd implement it in an extension method and then call it in the
controller.
To sum up:
Dogmatic answer: Service Layer
Pragmatic answer: Usually the controller
I would suggest sorting data from a table-data that is small enough to be useful in a dropdown list-should come from the DB already sorted via the query. To me, that makes the model the place the sort is applied.
If you are determined to do the sort by hand, I think there are good arguments for using either the model or controller as your preferred spot for logic. The limitation would be your particular framework. I prefer to manage data solely in the model. I use the controller to marry data(model) and presentation(view) as I've been (self)taught.
Whilst I agree in principle with the idea that sorting is Business Logic because by breaking it down to it's origin you would end up with something like "The client would like the Product page to display with the images sorted by date" then it becomes clear that the sort order for data is typically not arbitrary - even if there is no sorting as that's still a business decision by omission (an empty list is still a list).
BUT... These answer don't seem to take into account the advances in ORM technology, I can only talk in relation to the Entity Framework (let's avoid an argument about whether this is true ORM, that's not the point) from Microsoft as that's what I use, but I'm sure other ORMs offer similar functionality.
If I create a Strongly Typed view for a Product class using MS MVC and the Entity Framework and there is a foreign key relationship between the Product and Image table (e.g. FK_Product_Image_ProductId) then I would out-of-the-box be able to quickly sort the images during their display using something like this in the view:
#foreach(Image i in Model.Image.OrderBy(e => e.DisplayOrder)){ //etc etc... }
There was mention of a specific Business Logic layer, which I also use to perform 80% of my business logic, but I'm not going to write sort functionality into my Business Logic layer that mimics something that comes out-of-the-box from the Entity Framework.
I don't think there's a correct answer to this question, other than to say that; you should abstract complex business logic where possible but not at the cost of reinventing the wheel.
Assume that you have MVC website, WebForms website and a mobile application.
If you want sorting to be consistent between these presentation layers, then I'd say sort outside of the presentation layer. Service would be a good candidate.
Otherwise, I would store that logic in a view model. Why? Because it'll be reusable and easily testable.
Out of the three you have listed, I would say that it belongs in the controller. I don't really like placing this sort of logic in the controller, though. I usually create a service layer that the controller communicates with that will be responsible for communicating with the data store and handling sorting logic. For small applications it is fine sitting in the controller, though.
This is a question asked with the asp.net in mind, but since somebody did mention Rails, I thought it would be interesting to consider the problem in that context. In Rails, it is natural and pretty common to perform the sorting along with the retrieval as a controller action, since the framework and ActiveRecord/ActiveQuery api provisions for it. On the other hand, it is possible to define some sort of custom sort order for static items and put that in the model to be used by the controller, so the model can play a part in the sorting logic even though it does not carry out the operation directly. Whatever it is, it can be safe to say that putting the sort logic in the view is generally frown upon.
I'm slightly amused that some answers are absolutely against putting the sort in either the controller or the model, and I find them too pedantic for my taste, but I suppose it depends on the nature of the framework used and the usual conventions associated with it. I also agree with Bill K's comment that having the separation in the first place is more important.

Scope of viewmodels in asp.net MVC 3

I have read online that it is bad practice to use a "kitchen sink" model:
Rule #3 – The View dictates the design of the ViewModel. Only what is
required to render a View is passed in with the ViewModel.
If a Customer object has fifty properties, but one component only
shows their name, then we create a custom ViewModel type with only
those two properties.
Jimmy Bogard's subsequent explanation of how this is good, however, left me a little questioning. It'd be so easy to have my Model just contain a list of Customers, I could even use my POCO's.
So now I get to create custom little view model fragments for every page on the site? Every page that uses a Customer property would get one, but of course could not be shared since some of the information is extraneous, if one page used Age but not Name, for example. Two new mini view model classes right?
This is very time consuming, and seems like it'll lead to a million little custom view models - can someone elaborate as to the utility of this approach and why the easier approach is bad?
View model class can be used not only to transfer values, but it also defines data types (data annotations), validation rules and relations different then ones used in model. Some advantages that come to my mind right now:
There are different validation rules when you change user's password,
change his basic data or his subscription setting. It can be
complicated to define all these rules in one model class. It looks
much better and cleaner when different view models are used.
Using view model can also give you performance advantages. If you
want to display user list, you can define view model with id and name
only and use index to retrieve it from database. If you retrieved
whole objects and pass it to view, you transfer more data from
database than you need to.
You can define display, and editor templates for view models and reuse them on different pages using html helpers. It looks much worse, when you define templates for model POCOs.
If you would use your POCO objects as view models, you would essentially be showing your private objects and break the encapsulation. This in turn would make your model hard to change without altering the corresponding views.
Your data objects may contain details that are appropriate only to the data access layer. If you expose those things to the view, someone might alter those values that you did not expect to be altered and cause bugs.
Many of the same reasons as for having private members in OO languages apply to this reasoning. That being said, it's still very often broken because it's a lot of extra work to create all these "throw-away" models that only gets used once. There exists frameworks for creating these sorts of models, though the name eludes me, that can tie objects together and pick out the interesting properties only which takes away some of the drudgery from creating specific view models.
Your View Model tells the View how data should be shown. It expresses the model. I don't think its necessary to have two view models unless you have two ways to express your model. Just because you have two pages, doesn't mean you will be showing the data any different way, so I wouldn't waste time making two mini View Models when it can be in one reusable view model, Imagine if later you have a page that needs Name and Age, you would create another view model? It's absolutely silly. However, if you had two pages both showing 'Age' and it needed to be shown in a different way, then I would create another one.

How do you handle 'actions' on resources in a RESTful design, like marking an email read?

How would you integrate things like this in a RESTful design?
Marking an email as read
Voting on a story
Reporting a message as inappropriate
Additionally, how would you do it in such a way that one could make a small icon link or button to do the action without too much wizardry?
That depends on what you're doing. Sometimes all it takes is shifting your viewpoint from "performing an action on a resource" to "creating another, different, but related resource."
Voting on a story is easy: a Vote resource that you can create, review, etc. Same thing with a Report. This can be applied to anything, instead of marking an Order as submitted, it instead would have a Submission, etc. The key is to figure out how to transfigure your verb into a noun.
Marking an email as read is a bit different. What I would do for that is to use a virtual attribute: creating your own setter methods on your model (mark_as_read=, for instance) will let you pass mark_as_read through the params array in an #Update action.
To take the example of voting on a story. What you would do is create a Vote model, which belongs to a Story. Create a Votes controller, and have it nested off the Stories controller in your routes file. then, you can use your nested resource routes (passing in your Story record) to easily create votes scoped to the individual story.
Note that the resource doesn't necessarily have to be backed by a database model, although it would be proper form. You could always simply modify the Story record, in this case, while maintaining the RESTfulness and the ability to easily expand to a full model if needed.
This is an indispensable resource for anything REST:
http://oreilly.com/catalog/9780596529260/restful web services

Resources