How to validate data from a controller in a model? - ruby-on-rails

I have data in my controller that is being received from another rails app and database (this has to be in the controller) I want to get this data so I can validate it in my model before allowing another step in a wizard (see my other question for some code examples)
My Problem is that I cannot directly grab this data from the controller in my model as this violates MVC.
My Question is how would I go about checking the controllers data in my Model?
Do I have to load this data / true - false response in a view and then link this to my Model? (I don't really want this to show in the view and haven't quite worked out how to do this)
Do I need to pass this data to a route i.e example/data.json and then check this in my Model? (I also haven't worked out how to use this data.json from there in my model)
Any help / steering in the right direction would be very useful. (also i cannot use a gem to do this)

At first, please be double double sure that you don't validate a model by data which it does not contain by itself. Model should validate its current state but not a way it came to this state (e.g. which user put a model to this state).
At second, you should never use controller methods in a model. If controller contains some business logic, extract that logic into a third class which will be used by both controller and model.
Moreover, you have a data in a controller and you have an access to the model, right?. Therefore, if you are in a controller method, for instance in a before filter or action, you could take that data and pass it to the model, like this:
def controller method
hey_model.is_this_correct?(data)
end
If you say that that data must be checked after controller has responded to a request (for example, at the next wizard step, i.e. at the next request), then you definitely must store that value somewhere between requests.
This is the very point of stateless HTTP. No data is saved between requests until you explicitly do that. You could store your value in cookies or in database.

I understand that the question was a while ago but for those who are still searching, I found the exact answer, how to pass the information from the controller to a model.
With this line everything is solved
var = request.env['target_model'].sudo().function_in_your_model(data)
var is a variable in case you need to handle that data in the controller, target_model is the model where you want to send the data, function_in_your_model is the function where you are going to handle the data already in the model, and inside this function you send the data that you need.

Related

avoid GET_ENTITY call on bindElement for data already loaded in get_entityset

I have a Master Detail Detail-Detail Application:
Master: List of Users
Detail: Table with Qualifications of the user
Detail-Detail: Form to Edit the Qualifications
In the Detail View I have all the informations I need for the Form in the Detail-Detail view.
when I get the path of the selected listItem in the Detail View and then do a bindElement in my DetailDetail View a new Request for GET_ENTITY is called in my backend. How can I avoid this call as I already have all the data I need in my Detail View?
I could work around this issue by using a local JSON Model for the data I want to edit, but as I would like to use .hasPendingChanges in my Edit View I guess I need to bind to the original oDataModel, but as mentioned would like to avoid the GET_ENTITY backend call.
When you are binding an OData context if you call an entity the you will end in a request. i.e:
Think in a /Order('123') context then you need to bind another entity like /Order('123')/Location this is going to trigger a network request but in the case of any data like ID /Order('123')/ID this dont do any network request because properties do not trigger requests.
OData Model
Requests to the back end are triggered by list bindings
(ODataListBinding), context bindings (ODataContextBinding), and CRUD
functions provided by the ODataModel. Property bindings
(ODataPropertyBindings) do not trigger requests.
As you said you can workaround it using a JSONModel but then you will need to maintain two models, create validations, etc.
Hope this clarification helps.

understanding MVC in simple words

i checked google, books etc but all defines it differently and made me highly confused. Please describe it simply that what parts does what and contains what or can ?
lets start with
CONTROLLER:
MVC always start with the CONTROLLER. its connects your VIEW and your MODEL. CONTROLLERS are responsible for your business logic like validation, computations, etc.
MODEL:
responsible for obtaining/storing data in your database.
VIEW:
displays data, your User interface.
The Model-View-Controller as it implies contains three components when
this model is implemented:
The Model - This should take care of all the operations which deal
with the data required (in other words the business logic) for the
application, which is implementing the MVC model from now onwards will
be referred to as by the MVC application. The operations can mean
reading, writing data into the database, getting information from
remote machines via network, time consuming operations etc. The model
should also inform the view about any changes to the data happening in
the background. The View - This component takes care of presenting the
data to the user. With respect to the context of this article, i.e.,
WinForms, the view class will be tied around with the Form which will
be shown to the user. The Controller - This is the center and
important component of the MVC pattern as it ties the Model and View
together. The Model which manipulates the data and the View which
presents the data to the user does not know the existence of each
other or they interact directly with each other. It is the controller
which acts as an intermediary and ties them together. For example, the
controller takes the input from the user such as a button click and
informs the model to take appropriate action, if there should be an
action that needs to be initiated to manipulate the project data.
Check here
The View is the parts of the application that handles the display of the data.
You can say it GUI of your web application. It donot have any logic say database conenction logic.For example , if you want to display list of students from the DB , one way is put the select query in the .asp.,.cshtml,.vbhtml file and show the reult there . But in MVC view will have code of displaying recodes and model will have the code fore retriving it. Most often the views are created from the model data.
The Model is the part of the application that handles the logic for the application data.
Often model objects retrieve data (and store data) from a database.
The Controller is the part of the application that handles user interaction.
Typically controllers read data from a view, control user input, and send input data to the model.
It connect the view to model , model to view and user request for some page to view.
When user enter the url like ".../Home/Index" then it goes to the Controller first . There can be many controllers , here it will go to "Home" controller class and in that class it will call the "Index" action or say "method". That method will return the "Index.cshtml/Index.vbhtml/Index.asp" view back to user as response.
MVC seperate tha main logic from the view and controller is the one who handel those.

ZF2 - database and models

I followed this examples http://framework.zend.com/manual/2.2/en/user-guide/database-and-models.html to create a model and a way to save it to a database.
But I don't like the idea of using the AlubumTable-class in my controller as I think this creates too much dependencies. I just want to add the save(), fetchAll(), etc. methods to my model so that I don't have to care about how to save my models inside my controller.
If I want to change the way my models get stored e.g. from a database to a REST-service I would have to rewrite every part of my controller where I get or store models instead of just changing the save() etc. methods in my model.
Are there any tutorials for my way or is this just a stupid idea? :)
The concern you have is actually OK, but you have to realize that the AlbumTable is nothing but a layer between your Controller and the Database. The AlbumTable actually is the one thing with the dependency, not the controller.
The Controller will always need some sort of "Service" or "Gateway" (which would be AlbumTable) to get access to the Data from the DB.
Also i do not understand what you mean by "i want to change the way my models get stored" - You should always store the MODEL into your Service. In the given example the Model is Album and the Service is AlbumTable. No matter where the data comes from - REST, RPC, "normal HTTP", you would always store the Album and not some ArrayData or whatnot. You'd rather try to implement a function inside your model like exchangeArray(), exchangeJson().
You may want to make your "problem" more clear to us...

ASP.NET MVC 4 - Update Model from View

I'm playing around with ASP.NET MVC 4, but I have some problems with understanding. For better explanation I will use a simple "synthetic" situation.
Let's say I have model Person with 2 properties:
string Name
PersonType Type (e.g. Student, Employee, Military...)
Let's say in my controller I have private property Person. I can initialize this object in Index method, pass into View and build html page. Ok.
Now when user updates one of fields of person instance at the client side (he can input a new person name or select new person type using dropdown list), I want to update my model immediately. So, my general question is How can I achieve it?
Obvious solution for me: I can send an ajax request to controller from JS with new data. I thought that I can call controller's method UpdateName(string name) and update manually property Name with new data. BUT my person instance is NULL inside of this method! My second question is Why I can't access to initilized model object from other method? I think it's all about my bad understanding of client server interaction.
The final case of my situation: when user click's on the button "Save" I want to save created person into file on the server side, but I don't want to use any forms and receive all needed data just after clicking this button (because in my real task I can't use forms and also I can't receive all needed fields from html page after button clicking).
I have found the dirty solution. In JS I created another class Person with same properties. Now I can update instance of this class when I want and pass json data to server for saving it.
Is there any better solutions?
Its not that dirty to have javascript objects to represent your model. In fact thats how I do it. I use KnockoutJS to give me a client side model - which is essentially the MVVM pattern.
You are trying to use the MVC model in a way which you can't. However, the Knockout model you can use how you wish. You basically have a javascript representation of your server side model and once you are done with it you send it to the server.
In order for your server side methods to pick up your client side model you simply have to ensure the post request contains the data and as long as properties names are the same in the parameters of the method they will match themselves.
Why I can't access to initilized model object from other method?
Because it's not initialized anymore. Don't use the controller class to store persistent data across requests. The controller object is disposed after a request completes and then re-initialized on a new request. So anything that one action methods saves at the class level is gone when you get to another action method. Each request from the client to the server should be considered a fully isolated event, independent of any previous requests.
When you want to save your model, what you would do in that action is re-fetch it from the database, apply the changes, and save it back to the database.
but I don't want to use any forms
I'm not really sure what you mean here. Do you mean you want to use AJAX instead of POSTing the page directly? If so, that's fine. There are probably a number of tools out there to help you, personally I often just create a form anyway but instead of a submit button I have a plain button and add some JavaScript code (using jQuery) to serialize the form and perform an AJAX POST.
As long as the keys for the POST values map to your model fields in the same way they would in an out-of-the-box form, then your action method will still be able to receive the proper model type. On the server-side it doesn't matter if it's from an AJAX call or a normal POST. The difference, however, is that the response for an AJAX call should probably be in JSON format instead of responding with a view.
So instead of this:
return View(someModel);
You might have something like this:
return Json(someModel);

Best MVC way to handle multiple requests between view and model

I have a .net application with a Form layer, a DB model layer (entity framework) and a Controller layer between this two layers.
I need to handle this situation:
User presses a button to edit some params
The form needs to request some DB data that represents the current state of those params
Possibly, the user request could be rejected because is N/A to current situation, in this case an error message box should be shown
A modal form is shown, the user changes params and confirm
Changes are made in the DB model
That's pretty simple.
The fact is that, at point 4, we need some of the data we already processed at point 2.
In particular:
at point 2 we request some data to the DB model, that data is likely not to be in cache, so a SQL query is performed
that data is processed by a local LINQ
state of several checkboxes to show in the modal form is returned
at point 4 we need again LINQ processed data
since we came from the Form layer, we do not have that data anymore
therefore data is requested again to the DB model, but this time it's in cache
that data is processed again by local LINQ
Is it worth to re-load and re-process data to maintain the MVC pattern?
I don't know how it works exactly in VB.NET, but if we look at this problem in a pure "MVC" way (at least, how I understand it), something is not right.
In this step, when the click is done, the form call the controller (all action pass by the controller)
The controller then needs to do the validation. If it needs the database to do that, so be it. Then, it redirect the user to a view. (Should it be a message box or another form to enter data)
Here, the user do the change in the form and then click on a button to submit. In this button, you call the controller again (another function/action).
In the controller, you can do the needed validation and insert/update the data in the database via LINQ. Then, you can redirect to the view.
Since a lot of time could have passed between the step 2 and step 4 and that the data could have changed between the 2 calls, I think that doing the request 2 times is ok. Also, since they are 2 different function in the controller, I don't think you have the choice.
That's how I see it, but I can be wrong :)
EDIT
I didn't know that the query to the database were time consuming and that it was an issue.If the absolute goal is to NOT make the user wait twice since time is important in this application, I guess you could store the object that you get at step 2 in memory and retrieve it with the controller (with some kind of helper class). It's like doing the query in the database, but in the memory. If you use the repository pattern, then the programmer who's coding the logic in the controller will not even know that he's querying something else than the database since it's another level of abstraction. You could free the memory right after the step 4.
Oh I'm not 100% sure but the flow pattern in your question does not look right?
The usual procedure is to DISPLAY the DATA and have an edit button there with the dataview
So you may have something like
Function ShowAddressDetails(OwnerId as long) as ActionResult
And your ActionResult is usually a MODEL that is to be passed to the VIEW
maybe (keeping with the address record sample) something like...
Return View(AddressRecordModel)
where the address record is extracted from SQL DB using the OwnerId parameter
And in your VIEW where your EDIT button is,
You have at least two choices,
Those being
1. Reload data from SQL (used where data may have changed since last action)
2. Pass the already loaded Model (Used where the data hasnt changed)
which would mean tha you have either (or both) of the following
Function EditAddressDetails(OwnerId as long) as ActionResult
or
Function EditAddressDetails(Model as AddressRecordModel) as ActionResult
Alternatively you may have "CHILDACTION"s as opposed to "ACTION"'s
Also do not forget the following...
in a HTTP GET request, the model is passed from the CONTROLLER TO the VIEW
in a HTTP POST request the Model is passed from the VIEW to the CONTROLLER
So you should indeed have the model (data)?
Finally if the sequence is ONLY used by ONE user then the data should not have changed between requests UNLESS and EDIT/AMEND/UPDATE request was completed successfully.

Resources