Backbone and Laravel: Prevent access to Laravel controller method - url

First of all, sorry for my bad english language skills.
I am using Laravel and Backbone.js for small web app. In my backbone collection I'am defining urlRoot: 'test/cont1'. How can I "allow" backbone to asynchronously go to that URL but prevent user to manually go to the same URL by typing it in web browser (User will then get some json response that i don't want for him to see).

Don't know if this is what you want but you could add a filter and simply do if ( ! Request::ajax()) App::abort();
EDIT: a better example...
Route::filter('api', function($route, $request)
{
if ( ! $request->ajax()) App::abort(404);
});
Then in your controllers add the api filter.

Related

Adding AngularJS to existing ruby on rails app

I'm thinking about adding AngularJS to an existing app.
The app is an event management app with a dashboard action for each event.
So we have something like http://localhost:3000/events/2/dashboard
We are trying to make the dashboard view more user friendly by adding AngularJS.
The goal is to implement a controller which will retrieve the event id to make calls to other services and populate the results into the view.
I've read about the $routeParams but in most of the case the examples were dealing with single page applications with their own templates.
Is there any clean way to just retrieve the event id param from the url?
Any help would be highly appreciated.
By using the angularUI router you can retrieve the event_id param from the url and you can also have nested views.
angular
.module('paisApp')
.config ['$stateProvider', '$urlRouterProvider', ($stateProvider, $urlRouterProvider) ->
$urlRouterProvider
.otherwise("/")
# Define 'app' states. The order of the state is important.
$stateProvider
.state "event_dashboard",
parent: "default"
url: "/events/:event_id/dashboard"
views:
"":
controller: "EventsController"
templateUrl: "/assets/events/dashboard.html.erb"
Now in your events controller you can use the following to access the event_id
$stateParams['event_id']

Ruby on rails how to make website that doesn't refresh the page

I'm not even sure how to ask my question.
I know the basics of ruby on rails and I can make a web app. but I now have a project where I want to have a button on a view that sends data to the controller, but I don't want the controller to send me to a different view, instead I want it to send data back to me (maybe in Json format) and populate something in the view with that data retrieved from the database.
Is this possible? If so how would I go about doing it? What tools do I need if this kind of functionality isn't built into rails itself? I don't know anything about it but could ajax help?
Thanks for the guidance!
You have to make it with javascript.
In your case I advise you to use a simple ajax request with jQuery.
http://api.jquery.com/jquery.ajax/
Jquery is a javascript library that allow you to do this.
1) Include jquery in your html:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
2) Make the ajax query:
$.ajax({
url: "/api/your_url",
data: {
test: "parameter send to the rails controller and stored into params"
},
success: function( data ) {
console.log(data);
}
});
What you are referring to is called Ajax. You can use XmlHttpRequest in your client side javascript to send an asynchronous request to the server and register a callback function that will be called on the client when the server responds. In the callback function you can update your webpage with the new information.

JQueryUI AutoComplete Filtering

I have a JQueryUI AutoComplete in my application that allows a User to search for other users in the system. This is actually handled by a JavaScript array loaded in the client during form load. However, I am being told now that, by default, users should only search for other users in the same site they are in. Then, optionally, they can expand that search for users company-wide.
I have come up with a few ways to handle this .. all of which are pretty kludgy. Is there a "right way" to do this before I go down that road?
Well, You can filter your data using request object & response event in source option. Its up to you how you want to customize but this will get you started..
jQuery Autocomplete API < Look up response & request usage.
$('#controlID').autocomplete({
source: function(request, response){
// add your data manipulation logic here...
}
});
Also, you can access the current user input using 'request.term'

Backbone without Hashes?

I think I'm trying to use Backbone in an unintended way, and I couldn't really find much on it. Basically I have a Rails app that is serving up the views. I want to keep the regular navigation (as in page reloading), but let backbone see the route and setup certain parts of the templates on that page, handle the models, and all of that good stuff. So basically I'm using Backbone to handle all of my complicated javascript without making it a "single page app". Would enabling PushState break my absolute paths in older browsers? eg: "http://localhost:3000/projects" matching the route "projects".
PushState will not work in old browsers like IE6, but you could use different technique, for example you could use jQuery selectors and check whether you're on the particular page:
if ($('#login-page').length > 0) {
// we're on the login page
// ..initialize login page related backbone collections and views
}
..or you could store action/controller name somewhere in the html using data attribute: <body data-action="edit" data-controller="post"> and check it in javascript va4 $body = $('body'); if ($body.data('action') == 'edit' && $body.data('controller') == 'posts') {} etc.
..or you could have separate js file for each action/controller pair and include it on demand.

Backbone.js with Rails

I'm currently trying Backbone.js along with a rails app. My problem is, that I don't know how to implement the Backbone controllers and views with my rails app. I've read a lot of tutorials, but they are always using just one controller in backbone.js.
For example, I have two controllers in rails.
Activities Controller
Includes two views, a google map and a search field. The google map is inserted with a backbone view, the searchfield is in HTML and gets its functionality through a backbone view.
The search field should fetch data from my rails model and display markers inside the map.
And the other one is
Users Controller
Here the users profile is viewed, and I want to add some ajax functionality like updating values and other things
In my application.js I start the app using
var App = {
Views: {},
Controllers: {},
Collections: {},
init: function() {
new App.Controllers.Activities();
new App.Controllers.Users();
Backbone.history.start();
}
};
$(function() {
App.init();
});
The problem is, that I don't need the Activities controller in my User Profile and the Users controller in the Rails Activities controller. How could I solve this? Should I try reading the current URL within javascript and then decide which controller is used?
Or should I put the JavaScript file into the application.html.erb and then decide here which controller should be used?
Or is this the wrong way to use backbone.js controllers?
Am I getting sth wrong with the structure of backbone.js? Or am I using the Controllers in a wrong way?
Another question is, how to add little JavaScript, in particular jQuery, functionality through Backbone.js? For example, I want to remove the label inside a field, when the user clicks into the field. Or I want to do some tab-functionality and just toggle the visibility of some elements.
Should I create for each element that is using javascript a Backbone view? Or is this overload?
Hope I made myself clear and anybody can help,
thx!
Why not make use of the routes feature Backbone provides to decide which method to call? The activities controller would contain only routes use for activities, the user controller only for the user handling, and so forth.
Like this you can instantiate the controller just as you do and the routing will decide what happens based on the current location's hash.
If you can't use links with hashes (or there are no such links on your page), I'd simply name my view containers specific enough to attach events only for the current view when needed.
jQuery plugins etc. belong into views IMO. Same goes for your tabs and input hint toggle.
Update
On a general level (and I would not necessarily recommend doing it this way): If you have two methods:
// should be only called for the 'Foo' controller
function foo() {
alert("FOO");
};
// should be only called for the 'Bar' controller
function bar() {
alert("BAR");
};
and want to call only one of them depending on the current Rails controller, create a small helper:
e.g. in you *helpers/application_helper.rb*
def body_class
controller.controller_name
end
then call this method in your layout file (or header partial):
<body class="<%= body_class %>">
…
and use e.g. jQuery to "split" your JS execution:
if ($('body').hasClass('foo')) {
foo();
} else if ($('body').hasClass('bar')) {
bar();
}
I personally use jammit (from the same author of backbone). You can group stylesheets and javascripts files by module and use them on your different pages. So you create a module for your activities view and another for your user view each requiring the necessary JavaScript file. Two nice things about this:
you have only code used on the page loaded on the page
jammit comprsses everything for you
This is the way to go when not creating a single page web app where you relies on # routes to navigate from one controller to another. In your case you have multiple single page apps inside a main rails app.
Im a Backbone.js newb, so please someone correct me if Im wrong, but I think youre confusing what Backbone controllers are used for.
Backbone.js controllers basically consists of hashbang routes(similar to Rails routes) and actions that these routes call. For instance if you have a rails route that will render a view at http://mysite.com/backbone_test and you have a following backbone route:
var MyController = Backbone.Controller.extend({
routes: {
"foo/:bar": "myFirstFunction"
},
myFirstFunction: function(bar){
console.log(bar);
});
then if you go to http://mysite.com/backbone_test#foo/THIS-IS-AMAZING then MyController.MyFirstFunction gets executed and "THIS-IS-AMAZING" gets logged in JS console.
Unless you have a direct need for this sort of hashbang-related functionality, such as saving a state of your JavaScript application via an url (for example: http://my.app.com/#key=value&key=value&ad-infinitum=true ) Id advise against using Backbone controllers. You can get all of the functionality u described via Models Collections and Views.
Nice thing about Controllers and Backbone in general is that its modular and different parts can be used independently.
I guess the summary of this answer is that if you dont have a single page javascript application, do not use Backbone Controllers, rely on your rails controllers instead.

Resources