Rails Gem: Ajaxful_rating route problem - ruby-on-rails

I'm trying to get ajaxful_rating to work with my rails installation.
I have everything running find until a user clicks on a star to rate.
When I click a star, the browser url points http://localhost:3000/entries/1/rate?dimension=design&show_user_rating=false&small=true&stars=4
and I get this error: No route matches "/entries/1/rate"
But my routes say:
resources :entries do
collection do
...
end
member do
post 'rate'
put 'submit'
end
Is there something I'm missing? Some js not included? All I have included is jquery right now.
Edit
try {
Element.update("ajaxful_rating_design_no-small_entry_1", "<ul class=\"ajaxful-rating\"><li class=\"show-value\" style=\"width: 60.0%\">Global rating average: 3.0 out of 5</li><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>");
new Effect.Highlight("ajaxful_rating_design_no-small_entry_1",{});
} catch (e) { alert('RJS error:\n\n' + e.toString()); alert('Element.update(\"ajaxful_rating_design_no-small_entry_1\", \"<ul class=\\\"ajaxful-rating\\\"><li class=\\\"show-value\\\" style=\\\"width: 60.0%\\\">Global rating average: 3.0 out of 5</li><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>\");\nnew Effect.Highlight(\"ajaxful_rating_design_no-small_entry_1\",{});'); throw e }
This is what my server says when I click on a rating.

Your application is sending a GET request (the parameters are passed in the URL), but you declared a POST route.
Changing post 'rate' to get 'rate' will allow this request to go through.
The other possibility is that your application is generating a GET on the client side when it should be generating a POST. I'd need to look at your view code to diagnose that one.

Related

Specify route rules, and route to different components

I know how to to specify routes for page components using Mason::Plugin::RouterSimple, for example given a url of:
/archives/2015/07
I can create a component archives.mc as this:
<%class>
route "{year:[0-9]{4}}/{month:[0-9]{2}}";
</%class>
Archives for the month of <% $.month %>/<% $.year %>
and similarly I can create a news.mc component that will handle urls of:
/news/2012/04
and that's fine (and very elegant!) but now what I want is to be able to handle urls like the following ones:
/john/archives/2014/12
/john/news/2014/03
/peter/news/2015/09
/bill/archives/2012/06
etc. I know I can write the route rules as:
<%class>
route "{user:[a-z]+}/archives/{year:[0-9]{4}}/{month:[0-9]{2}}", { action=> 'archives' };
route "{user:[a-z]+}/news/{year:[0-9]{4}}/{month:[0-9]{2}}", { action=> 'news' };
</%class>
but then the requests have to be handled by two different components. How can I route a request to different components? archives.mc and news.mc won't be matched by Mason because there's a username before the name of the component.
The problem is that, while urs like /archives/2014/12 can be easily handled by an /archives.mc component, for urls like /john/archives/2014/12 and /bill/archives/2012/06 it's not clear where to put the archives component.
Mason will try to match the following components (it's a simplified list, please see Mason::Manual::RequestDispatch):
...
/john/archives.{mp,mc}
/john/dhandler.{mp,mc}
/john.{mp,mc}
but finally...
/dhandler.{mp,mc}
So my idea is to put a dhandler.mc component in the root directory:
<%class>
route "{user:[a-z]+}/archives/{year:[0-9]{4}}/{month:[0-9]{2}}", { action=> 'archives' };
route "{user:[a-z]+}/news/{year:[0-9]{4}}/{month:[0-9]{2}}", { action=> 'news' };
</%class>
<%init>
$m->comp($.action.'.mi', user=>$.user, year=>$.year, month=>$.month);
</%init>
If the url matches the first route, it will call the archives.mi component:
<%class>
has 'user';
has 'year';
has 'month';
</%class>
<% $.user %>'s archives for the month of <% $.month %>/<% $.year %>
(I used a .mi component so it will be accessible only internally).
The dhandler can be improved (better regexp, can check users from a database table and deny the request, etc.)
Since my archives and news components can accept POST/GET data, and since I want to accept any data, I can just pass everything with:
$m->comp($._action.'.mi', %{$.args});
Not too elegand, but it looks like it does its work.

How to get MiniProfiler logs from the redirected request?

I have the MiniProfiler installed in my ASP.NET MVC 3 project running good but i got a problem, the MiniProfiler only shows logs from the last request and some "summary" of the whole site loading.
I have a form that posts to /MyForm and MyForm actionresult redirects to /Show and i get all logs for /Show but not all from /MyForm but i getting a summary how long time the /MyForm taked + the sql questions but i dont get the children logs from it.
Any ideas?
I found the similar issue of not showing the profiler-popup button in page, of a POST request after redirect. In my case, it was because of the result length exceeds the maximum Json string Length. To resolve this I set the size limit as below:
MiniProfiler.Settings.MaxJsonResponseSize = int.MaxValue
I put it in Application_Start().
I found the response:
In the global.asax, after the call to MiniProfiler.Stop(), add this code to prevent to tell the id of the logs at the ajax response.
//Se faccio il redirect tolgo il render del mini profiler
const string KEY_HEADER_MINIPROFILER = "X-MiniProfiler-Ids";
if (!string.IsNullOrEmpty(Response.RedirectLocation) && Response.Headers.AllKeys.Contains(KEY_HEADER_MINIPROFILER))
{
Response.Headers.Remove(KEY_HEADER_MINIPROFILER);
}
In the next page will be rendered also the log of the page that make the redirect
If you make itself the redirect with a javascript after an ajax request remember to make:
Response.RedirectLocation = "...."

extra users url when trying to combine backbone and rails

I have a rails app that uses backbone on the homepage. It has a search field in the navbar. If a user searches a name, a dropdown bar opens showing all the users with a specific letter in the name, at which point the user can click a link to any of the profiles. The Backbone collection 'Users" builds on the url like this, with 'key' representing the letter(s) entered in the search box.
var url = "users/search/" + key;
However, the app only uses backbone in a limited way. For example, after the user clicks on a link, there is a page change and they are taken to localhost:3000/users/28. I want the search bar to be available on a user's profile page, however, if I search a name from a profile page, the url (in the console logs) now becomes.
/users/users/search/" + key;
In other words, searching from a user's profile page adds an extra "users" into the search query (and a 404 not found error), even though the url for the ajax request the Users collection is like this
var url = "users/search/" + key;
Out of curiosity, I added a route to the routes.rb to try to deal with the '/users/users' situation
match '/users/search/:query' => 'users#getUsersByName', defaults: {format: :json}
match '/users/users/search/:query' => 'users#getUsersByName', defaults: {format: :json}
However, even though this eliminates the 404 error, and returns search results, if I click the link, to visit another user's profile (from a user's profile page), Rails is taking me to /users/users/28, because the link in the template is being tacked onto the base users url.
Can anyone recommend how I might go about dealing with this problem?
link in the template
<a href='users/{{= id }}'>
Users collection
window.Users = Backbone.Collection.extend({
model: User,
url:"users",
findByName:function (key) {
var url = "users/search/" + key;
console.log('findByName: ' + key);
var self = this;
$.ajax({
url:url,
dataType:"json"
success:function (data) {
It needs to have a forward slash before users. So instead of this
var url = "users/search/" + key;
Do
var url = "/users/search/" + key;

how to fetch json data from a remote server in a backbone.js app

I'm following an app example from this repo
and i started to build a similar app in my local machine using rails intead php for API, so i build apart the rails app in a specific root directory then in another root the backbone.js/JQM app calling rails api.
so i create the model and the collection in backbone with the urlRoot with: http://localhost:3000/api/clubs.json, that correspond to the local server url for retrieve a list of clubs
then i have tried to see in the javascript console what happen with these commands:
clubs = new ClubsCollection()
Object {length = 0 ...etc..}
clubs.fetch()
GET http://localhost:3000/api/clubs.json 200 OK
and the response is empty...
but when i call the url http://localhost:3000/api/clubs.json it returns the json clubs list correctly.
can you help me to understand the best way to do this call?
fetch is asynchronous. you have to wait for it to finish loading the data, and check the response then. This is typically done through the reset event:
clubs = new ClubsCollection();
clubs.on("reset", function(){
alert(clubs.length + " item(s) found");
});
clubs.fetch();
I have solved the problem using 'rack-cors' gem with the a basic config into
config/application.rb:
config.middleware.use Rack::Cors do
allow do
origins 'localhost'
resource '%r{/api/\$+.json}',
:headers => ['Origin', 'Accept', 'Content-Type'],
:methods => [:get, :put, :delete]
end
end
If you look at the backbone API there is a success callback that you can provide with the fetch() call, e.g.
clubs.fetch({
success : function(model, err) { // do something }
});
Like the other answer, fetch is asynchronous so you can't expect the results to be back by setting a break point after the .fetch() call.

Using the Symfony admin generator to let a user manage a subset of record

My first post here, hopefully It will be right! =)
I am creating a site to manage web application development using symfony 1.4 and doctrine.
My records consist for this problem of Project and ProjectFeatures
Now what I want to do is use the admin generator to let users manage the features for one project thru a link constraining all the returned features by project_id, that would look like: http://mysite/member/project/:project_id/features
in my routing.yml configuration, I have:
member_project_feature:
class: sfDoctrineRouteCollection
options:
model: ProjectFeature
module: memberProjectFeature
prefix_path: /member/project/:project_id/features
with_show: true
column: id
with_wildcard_routes: true
project_id is an existing column in the model ProjectFeature,
I will use a custom query to retrieve features only by that project_id.
Now I can generate a url to link to that admin generator module without error using:
url_for('member_project_feature', array('project_id' => $project['id']))
And the routing system does recognise the url:
May 04 14:30:59 symfony [info] {sfPatternRouting} Match route "member_project_feature" (/member/project/:project_id/features.:sf_format) for /member/project/1/features with parameters array ( 'module' => 'memberProjectFeature', 'action' => 'index', 'sf_format' => 'html', 'project_id' => '1',)
But the admin generator can't generate it's links inside it's templates with that prefix_path and returns error InvalidArgumentException with message The "/member/project/:project_id/features/:action/action.:sf_format" route has some missing mandatory parameters (:project_id).
Any idea?
Well I found my answer at this url: http://www.blogs.uni-osnabrueck.de/rotapken/?s=symfony
But I will give it here and shorten it because, stackoverflow is awesome and it should be there for a long time =)
1st - The routing configuration I used in my question is valid.
2nd - You need to add a method in the action file generated by the admin
public function execute($sfRequest)
{
// taken from http://www.blogs.uni-osnabrueck.de/rotapken/?s=symfony
$this->forward404Unless(
$project_id = $sfRequest->getUrlParameter('project_id'));
$this->forward404Unless(
$this->project = Doctrine::getTable('ttcWebProject')->find($project_id));
$this->getContext()->getRouting()
->setDefaultParameter('project_id', $project_id);
if ($id = $sfRequest->getUrlParameter('id'))
{
$this->getContext()->getRouting()->setDefaultParameter('id', $id);
}
$result = parent::execute($sfRequest);
return $result;
}
At this point the url gets generated correctly but here is the last step to get to the end result you most probably want to achieve:
3rd - To get the list by project_id I can either provide a table method in the generator.yml, a default value to the getFilterDefaults or this method in the action file:
protected function buildQuery ()
{
$q = parent::buildQuery();
$rootAlias = $q->getRootAlias();
$q->andWhere("{$rootAlias}.project_id = ?",
$this->getRequest()->getUrlParameter('project_id'));
return $q;
}
I'm not 100% certain about what you're trying to do here, but it sounds like you need the ProjectFeature::toParams method return the project_id.

Resources