Custom route for record.save() in ember - ruby-on-rails

In ember , I have a model called "Post" .
If i perform
record.save()
on creating a post , by default it posts to my /post url in Rails(backend). This works in my case. But for future uses, how do i specify a custom route? Let's say I want to post this model to my backend to a route called
"/post/save"
How do i make record.save() in ember to go to this route?

Adapters in ember manage how a model communicates with remote data. If you need to go outside of ember convention, you can create a custom adapter for your model that can point actions to different places.
ember generate adapter model-name
In your case, you want to call /post/save instead of /post when you create a post. You would overload the method urlForCreateRecord:
urlForCreateRecord(modelName, snapshot) {
return '/post/save';
}
Each url for an action (create, update, new, find, query) can be adjusted to fit your backend.

You can do that in the adapter of your post model.
Given your case, you need to add:
urlForCreateRecord () {
return this._super(...arguments) + '/save';
}
That url will only be used when the save method is creating the record (POST), when saveing already existing records (PATCH) you should use urlForUpdateRecord

Related

MVC Redirect to a different view in another controller

After a user has completed a form in MVC and the post action is underway, I am trying to redirect them back to another view within another model.
Eg. This form is a sub form of a main form and once the user has complete this sub form I want them to go back to the main form.
I thought the following might have done it, but it doesn't recognize the model...
//send back to edit page of the referral
return RedirectToAction("Edit", clientViewRecord.client);
Any suggestions are more that welcome...
You can't do it the way you are doing it. You are trying to pass a complex object in the url, and that just doesn't work. The best way to do this is using route values, but that requires you to build the route values specifically. Because of all this work, and the fact that the route values will be shown on the URL, you probably want this to be as simple a concise as possible. I suggest only passing the ID to the object, which you would then use to look up the object in the target action method.
For instance:
return RedirectToAction("Edit", new {id = clientViewRecord.client.ClientId});
The above assumes you at using standard MVC routing that takes an id parameter. and that client is a complex object and not just the id, in which case you'd just use id = clientViewRecord.client
A redirect is actually just a simple response. It has a status code (302 or 307 typically) and a Location response header that includes the URL you want to redirect to. Once the client receives this response, they will typically, then, request that URL via GET. Importantly, that's a brand new request, and the client will not include any data with it other than things that typically go along for the ride by default, like cookies.
Long and short, you cannot redirect with a "payload". That's just not how HTTP works. If you need the data after the redirect, you must persist it in some way, whether that be in a database or in the user's session.
If your intending to redirect to an action with the model. I could suggest using the tempdata to pass the model to the action method.
TempData["client"] = clientViewRecord.client;
return RedirectToAction("Edit");
public ActionResult Edit ()
{
if (TempData["client"] != null)
{
var client= TempData["client"] as Client ;
//to do...
}
}

Calling Web API with Singular or Plural Controller URIs

Most examples of Web API that I've seen show URIs in this format:
/api/values/ (returns all records)
/api/value/{id} (returns a specific record)
I can think of times I would not like this URI convention, but for my current project it's perfect. Though, it's not working for me and I don't know what I could have done to effect this. For me, I can have one or the other - singular or plural.
If my controller class is named ValuesController, then my Web API is
/api/values/
/api/values/{id}
If my controller class is named ValueController, then my Web API is
/api/value/
/api/value/{id}
I used ADO.NET Entity Data Model to create several entities in model designer. All have a singular naming convention. For example, Activity, State, Country, User, etc. Though, EF appears to create plural database tables no matter.
I created APIControllers for each of these entities. I've tried 2 naming conventions with my controllers - both plural and singular, but I am not seeing the expected (and desired) results with the URIs. The plural and singular Web API are always the same no matter what I try.
FYI, I just checked the default API that is created automatically (ValuesController). To return all records I have to specify /api/values/ and to return a single record I have to specify /api/values/{id} - both are plural and I'm sure it wasn't that way by default.
What effects this? Where is the logic that configures/recognizes a distinguished form of the URI for plural and singular?
The default route that is configured in Web API's RouteConfig.cs file specifies a parameter named controller, similar to this:
routes.MapHttpRoute("Default", "api/{controller}/{id}",
new { id = RouteParameter.Optional };
When you're making a call to either /api/values or /api/values/{id}, the route value for your controller will be values in both cases. Consequently, the controller that Web API resolves by convention will be the ValuesController.
(Note that there's no automatic pluralization performed whatsoever. You can implement a custom IHttpControllerSelector, if you really wanted to implement that behavior. I strongly recommend not to do that, though.)

Devise + Backbone.js, cannot create new user

Register view is rendered by backbone. When I submit the form to register a new user, I got the error like this.
I understand it's gonna check whether the email exists or not. But I don't know why I posted all my attributes but the backend seems not getting it.
I'd guess that your controller is looking at params[:user] to find the user's information but you don't have :user in your params. The manual talks about this:
Working with Rails
[...]
Similarly, Backbone PUTs and POSTs direct JSON representations of models, where by default Rails expects namespaced attributes. You can have your controllers filter attributes directly from params, or you can override toJSON in Backbone to add the extra wrapping Rails expects.
So adjust your controller to look at params rather than at something inside params or adjust your Backbone model's toJSON to look something like this:
toJSON: function() {
return { user: _.clone(this.attributes) };
}
If you change toJSON you'll want to adjust how you feed data to your templates to compensate for the toJSON return value change.

ActionLink/RouteLink based on URL not Controller

I have a controller that uses the following structure:
.com/Object/375
However, I can also use the following URL when I am accessing special admin rights
.com/Admin/Object/375
I use the same user controls whether you're in the Admin section or not, but they both point to the same Controller Object. I need for the links to maintain that URL structure and not try to kick an Admin user back to the Object controller. I am currently using the route name method, where these are my route names (in global.asax):
"Admin/-Object"
"Object/-Object"
"Object-Object"
These route names catch the following routes:
Admin/Object, Admin/Object/555, Object, Object/323
I then use the following in a route link
Html.RouteLink(id, Request.Url.Segments[1] + "-Object", new { id = id })
This works just fine, but has an odd smell - any other ideas?
To clarify: I need the URL to be properly created based on the current URL structure (with or without the Admin) and the routing will point to the correct controller (the same for both URLs) and the admin specific content will be injected into the page only if in the Admin section (based on URL).
Just to wrap this up, using ViewBag is probably a better idea because using the URL segment might result in unexpected errors, especialy if you move the controls or views around.

Url routing with database lookup?

I want to build a ASP.NET MVC site so that the controller for a specific url is stored in the database instead of the URL.
The reason for that is that i'm building a CMS system and the users should be able to change the template (controller) without changing the URL. I also think that the name of the controller is not relevant for the end users and i want clean URL:s.
I realise that i could just add all routes at application start, but for a system with like 100 000 pages it feels like a bad idea.
Is it possible to store the url:s in the database and make a lookup for each request and then map that request to a specific controller?
Basically you'll have to implement your own IRouteHandler.
Part of the answer and some example code is in Option 3 of this question's answer:
ASP.NET MVC custom routing for search
More information:
http://weblogs.asp.net/fredriknormen/archive/2007/11/18/asp-net-mvc-framework-create-your-own-iroutehandler.aspx
Why couldn't you just do something like this:
-- Global.asax.cs --
routes.MapRoute(null, // Route name
"content/{id}", // URL with parameters
new { Controller = "Content", Action = "Show", Id = (string) null }); // Parameter defaults
-- /Controllers/ContentController.cs --
public class ContentController : Controller
{
public ActionResult Show(string id)
{
// Lookup the 'content' (article, page, blog post, etc) in the repository (database, xml file, etc)
ContentRepository repository = new ContentRepository();
Content content = repository.FindContent(id);
return View(content);
}
}
Such that a request to your site www.yoursite.com/content/welcome-to-my-first-blog-post would call ContentController.Show("welcome-to-my-first-blog-post").
I suppose ASP.NET can do many of the same things as PHP. If so there is a simple approach.
With rewrite rules you can easily send any traffic to any URL of the 100K to the same place. On that destination you could simply use the server variables containing the URL requested by the client and extract the location. Look it up in the DB and send the corresponding data for that URL back to the client on-the-fly.
"for a system with like 100,000 pages it feels like a bad idea."
It is a bad idea if you are creating a routing system that cannot be reused. The basic {controller}/{action}/{id} schema points you in the direction of reuse. This schema can be extended/revamped/recreated according to your needs.
Instead of thinking about how many pages you have think about how your resources can be grouped.
Instead of creating a heavy routing system why not create an anchor link control (ascx) which allows user to only add valid internal links. Keep a table in the db of your templates and their controllers to populate the control with it.

Resources