I learned that is this how to access a model from other controller,
var book = Alloy.Models.instance('book');
And this is how to access a property of a model,
var name = book.get('name');
However in the console,the name logs [INFO] : { } , meaning this doesn't get its property value, and ofcourse the model has already a data saved on it. Thanks for your help!
You may have to fetch the collection first:
var books = Alloy.Collections.book;
books.fetch();
This will load all the models from the collection so you can use them.
although the above works, there are a few addtional points here.
the call is asynchronous in most cases so you should be getting the model in a callback which is not presented in the code above.
I dont know if fetching the collection everytime you want a model is the correct approach either? If the collection already exists you just need to get the model from the collection just using the id.
depending on the exact use case, you might just want to pass the model as a parameter from one controller to the next
Related
I'm working with two tables Video and Picture and I would like to regroup them using SQL instead of ruby. This is how I do it now :
#medias = (Video.all + Picture.all).sort_by { |model| model.created_at }
Is their a way to do the same thing only with SQL/ActiveRecord?
Since you don’t have the same columns in each model you could create a polymorphic relationship with a new model called media. Your Videos and Pictures would be associated with this new model and when you need to work on only your media you don’t need to worry about whether it is a video or a picture. I’m not sure if this fits into your schema and design since there is not much info to go on from your post but this might work if you wanted to take the time to restructure your schema. This would allow you to use the query interface to access media. See the Rails Guide here:
http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
You can create a media model with all the fields need to satisfy a Video or Picture object. The media model will also have a type field to keep track of what kind of media it is: Video or Picture.
Yes, using ActiveRecord's #order:
#video = Video.order(:created_at)
#pictures = Picture.order(:created_at)
#medias = #video.all + #pictures.all # Really bad idea!
Also calling all on the models like that will unnecessarily load them to memory. If you don't absolutely need all records at that time, then don't use all.
To run sql queries in Rails you could do this:
sql_statement = "Select * from ..."
#data = ActiveRecord::Base.connection.execute(sql_statement)
Then in your view you could simply reference the #data object
I am using the following code to render a pager:
#Html.BootstrapPager(Request.QueryString("Page"), Function(index) Url.Action("Index", "Posts", New With {.page = index}), 14000, System.Web.Configuration.WebConfigurationManager.AppSettings("PageSize"), 15)
My problem is that If I use Model.Count in place of the 14000 then I only get 1 page of records since I am using skip and take in the repository to pull only the need records. How can i in the view access the total number of published records so that I don't have to hard code the value into the view right now?
The original pager code is here. I converted it to VBNET am using it. It works fine if the record count is hardcoded.
This is the repo:
Dim posts As IEnumerable(Of PostSummaryDTO)
Using db As BetterBlogContext = New BetterBlogContext
posts = db.be_Posts.OrderByDescending(Function(x) x.DateCreated).Select(Function(s) New PostSummaryDTO With {.Id = s.PostRowID, .PostDateCreated = s.DateCreated, .PostSummary = s.Description, .PostTitle = s.Title, .IsPublished = s.IsPublished}).Skip((Page - 1) * PageSize).Take(PageSize).ToList()
Return posts.ToList
End Using
You need two different methods in the lower layer - one to get the total count and one to get the desired page - and then call them both from your controller, passing both results in the model to the view. As such, the model cannot be a collection of records; it must be an object with a property for a collection of records and a property for the count. Either that or use the ViewBag to pass the count.
What we do in my office is have a service layer to contain the business logic and repository to handle the data access. There is a single method in the repository to return an IQueryable that provides access to all the records for a particular table. There are then one or more methods in the service that call that repository method and use it in different ways. In this case, there might be a GetTotalCount method and a GetPage method in the service. Both would call the same repository method to get the same IQueryable and then the first method would call Count on the result while the second method would call Skip and Take. As Skip and Take don't force execution of the query, you'd also call ToArray or the like in that second method. The service might also have a GetRecord method that you would pass an ID and call FirstOrDefault inside to get a single record with a matching ID. You can roll the service and repository into a single class if you want but I'd recommend separating the business logic from the data access.
SCENARIO: After the user has successfully logged in, I want to create an Account object (Account class is a part of my model) and fetch and store the user's information in it. I want this Account object to be accessible to all my controllers (HomeController, AccountController etc) and also, I want the ability to edit its content from inside any controller. (1) How can I achieve this scenario? (2) How can I pass a model object from one controller to another?
I intend to keep it till the user logs out
Then you can use session. But I suggest not saving a lot of information. So for example you have this model or entity:
public class AccountModel {
public int Id {get;set;}
public string Username {get;set;}
// and a whole lot more of properties
}
I suggest you just store an identifier field, either the Id or the Username. Then when another request comes in and you need to either validate the request or update that same model, you can:
Fetch the data again for that user and all relevant information
Update the necessary fields
Save it in your database
So you would do something like:
// to save it in a session after logging in
Session["current_user_id"] = id_variable;
// to retrieve it from session after another request comes in
var id = (int)Session["current_user_id"];
// fetch from your database
// do the necessary update
// persist the changes
(1) How can I achieve this scenario?
You could retrieve the Account model from your datastore when you need to access it.
(2) How can I pass a model object from one controller to another?
See (1). Since you are retrieving it from the data store you don't need to be passing it around.
Is it possible to do an overload of the actions in the controller? I haven't found any info about it and when I tried, I got this error:
The current request for action 'Create' on controller type 'InterviewController' is >ambiguous between the following action methods:
System.Web.Mvc.ViewResult Create() on type >MvcApplication4.MvcApplication4.InterviewController
System.Web.Mvc.ViewResult Create(Int32) on type >MvcApplication4.MvcApplication4.InterviewController
I've tried to do this on another way and I also get a new error that I can't fix. In fact, I created a new action (called create_client instead of create)
I need 2 ways of creating an "opportunite".
I just call the action, and I receive an empty formular in which I just have to insert data.
From a client's page, I must create an "opportunite" with the client that's already completed when the form is displayed to the user. (there is a need of productivity, the user must perform actions as fast as possible).
In the table "opportunite", I've got a column called "FK_opp_client", which is equal to the column "idClient" from the client's table.
I don't get how I can do the second way.
I've created a new action in the controller.
'
' GET: /Opportunite/Create_client
Function Create_client(idclient) As ViewResult
'Dim FK_Client = (From e In db.client
'Where(e.idClient = idclient)
' Select e.nomCompteClient).ToString()
'ViewBag.FK_client = New SelectList(db.client, "idClient", "nomCompteClient", idclient)
Dim opportunite As opportunite = db.opportunite.Single(Function(o) o.idOpportunite = 5)
opportunite.FK_Client = idclient
ViewBag.FK_Client = New SelectList(db.client, "idClient", "nomCompteClient", opportunite.FK_Client)
Return View(opportunite)
End Function
I've tried a few things to get what I wanted, the last one was to copy what was done in the "Edit" action, but for an empty rank. (so I created an empty rank in my DB). I don't think it was a good idea (imagine someone wants to update the DB where idOpportunite = 5...)
Any better ideas?
If you want to keep those two methods under the same name, you will have to implement an ActionSelectionAttribute to decorate them, or use them with different verbs (for example POST and PUT). Please read more details on action method selection process here (old but still true).
Different approach might be making your parameter optional and make action to check if it has been passed or not (through nullable type).
NHibernate allows me to query a database and get an IList of objects in return. Suppose I get a list of a couple of dozen objects and modify a half-dozen or so. Does NHibernate have a way to persist changes to the collection, or do I have to persist each object as I change it?
Here's an example. Suppose I run the following code:
var hql = "from Project";
var query = session.CreateQuery(hql);
var myProjectList = query.List<Project>();
I will get back an IList that contains all projects. Now suppose I execute the following code:
var myNewProject = new Project("My New Project");
myProjectList .Add(myNewProject);
And let's say I do this several times, adding several new projects to the list. Now I'm ready to persist the changes to the collection.
I'd like to persist the changes by simply passing myProjectList to the current ISession for updating. But ISession.SaveOrUpdate() appears to take only individual objects, not collections like myProjectList. Is there a way that I can persist changes to myProjectList, or do I have to persist each new object as I create it? Thanks for your help.
David Veeneman
Foresight Systems
If you load objects like in your example - then yes you have to persist them one by one.
However, if you make a small design change, and load something like : Account that has an IList<Project> - if you specify cascade "what_cascade_you_need" in the mapping , then when you change the projects on Account , you only have to save Account and everything will get saved.