IMPORTANT NOTE: The id does not matter, it is same in all cases.
I am only seeing the name field, not description, hours, etc even though these aren't null.
I have declared all standard routes through resources (with default format json), not individually.
I have even tried creating a projects/show.json.jbuilder file:
json.name #project.name
json.description #project.description
json.hours #project.hours
json.ownername #project.ownername
My projects/show method:
#project = Project.find(params[:id])
render :json => #project
FIRST EDIT:
I added logger.debug right before defining #project in my show method.
Now in my command prompt window for the local server, I am seeing:
Started GET "/projects/12" for 127.0.0.1 at 2015-02-25 16:36:45 -0500
ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by ProjectsController#show as HTML
Parameters: {"id"=>"12"}
Project Load (0.1ms) SELECT "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT 1 [["id", 12]]
#<Project:0x007f95477e72f8>
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 51]]
Completed 200 OK in 42ms (Views: 15.2ms | ActiveRecord: 0.9ms)
I am wondering why I am seeing the "User Load" part, since my Project model does not belong to a User object or have any relationship with it (though in the past it may have had before that relationship was removed). Also, I don't think I saw
#<Project:0x007f95477e72f8>
earlier.
I solved my problem this way.
Basically, projects/12.json currently works and not projects/12. Since I am more interested in obtaining the data client side, it is ok for me. I would need a projects/show.html.erb page that calls all the project data through view helper methods, for the HTML to work.
def show
#project = Project.find(params[:id])
respond_to do |format|
format.html
format.json
end
end
projects/12.json works because I have a projects/show.json.jbuilder file (as I shared in my original question post):
json.name #project.name
json.description #project.description
json.hours #project.hours
json.ownername #project.ownername
Related
I have a simple photo gallery on a site, and am having some trouble when I invoke either the edit or delete paths. I click on the button and the page acts like it is going to load, then goes to an error page. Here is the trace from the console:
Started GET "/photos/17/edit" for 127.0.0.1 at 2015-10-12 09:41:08 -0700
Started GET "/photos/17/edit" for 127.0.0.1 at 2015-10-12 09:41:08 -0700
Processing by PhotosController#edit as HTML
Processing by PhotosController#edit as HTML
Parameters: {"id"=>"17"}
Parameters: {"id"=>"17"}
Photo Load (0.2ms) SELECT "photos".* FROM "photos" WHERE "photos"."id" = $1 LIMIT 1 [["id", 17]]
Photo Load (0.2ms) SELECT "photos".* FROM "photos" WHERE "photos"."id" = $1 LIMIT 1 [["id", 17]]
Album Load (7.9ms) SELECT "albums".* FROM "albums"
Album Load (7.9ms) SELECT "albums".* FROM "albums"
Rendered photos/_form.haml (35.7ms)
Rendered photos/_form.haml (35.7ms)
Rendered photos/edit.haml within layouts/application (38.9ms)
Rendered photos/edit.haml within layouts/application (38.9ms)
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Rendered layouts/_navbar.html.haml (5.0ms)
Rendered layouts/_navbar.html.haml (5.0ms)
Completed 200 OK in 187ms (Views: 174.4ms | ActiveRecord: 9.4ms)
Completed 200 OK in 187ms (Views: 174.4ms | ActiveRecord: 9.4ms)
Then I get this immediately after, before the edit page loads:
Started GET "/undefined" for 127.0.0.1 at 2015-10-12 09:41:08 -0700
Started GET "/undefined" for 127.0.0.1 at 2015-10-12 09:41:08 -0700
ActionController::RoutingError (No route matches [GET] "/undefined"):
I've looked over my controller and methods and haven't seen anything that would suggest the need for it to look for the /undefined path. What is worse is that it doesn't happen every time, which made me think there was something wrong with my ruby installation or something. If that was the case, it would not give the error on Heroku (which it does) and would probably error out in other applications I work on (which it doesn't).
Controller:
def update
respond_to do |format|
if #photo.update(photo_params)
format.html { redirect_to #photo, notice: 'Photo was successfully updated.' }
format.json { render :show, status: :ok, location: #photo }
else
format.html { render :edit }
format.json { render json: #photo.errors, status: :unprocessable_entity }
end
end
end
def destroy
#photo.destroy
respond_to do |format|
format.html { redirect_to photos_path, notice: 'Photo was successfully destroyed.' }
format.json { head :no_content }
end
end
Model:
class Photo < ActiveRecord::Base
mount_uploader :image, ImageUploader
belongs_to :album
validates_presence_of :image
end
When I notice that it is redirecting me, I can just browse to the picture itself fine (photos/8), but the edit path is still kicking me to the /undefined (photos/8/edit).
I realise (and hope) you might have solved this already, but I've been banging my head against the wall due to a similar problem - a GET request to /undefined route. Luckily, I was able to solve it and this might help people with similar problems.
To explain my situation - I have some AJAX calls and I suspected it might have something to do with that, even though I did not build up any URLs with variables that could be undefined.. or so I thought (I was partially right, though).
I was fetching some information (including image URLs to be rendered in view thereafter) based on data returned by an API in JSON format. I hope you see where I am going with this :)
Turns out one image (for that specific API request, I am sure there are other such cases which I haven't yet found) had no URL defined. As I passed the json data to a constructor, I expected the image URL to be defined and inserted that into the image src attribute. The URL was, however, apparently undefined. Therefore, instead of loading the image via absolute path to the API's CDN, as the src had no http(s)://, it tried to load it from local server. As the variable with image url was undefined, the image src attribute pointed to a relative /undefined route. Hence a GET request to "/undefined" route.
I should note that this was not an ajax call per se, the get request was a result of using data from ajax call to construct an image src attribute. The fact that I used that data for constructing a google maps infowindow HTML structure (which included an image in it) only compounded the problem as the missing image (due to undefined src) would only show up after clicking on a specific google maps marker.
So, for your case (while it might not be relevant for you anymore, might be for someone else) - make sure you look at image src attributes as images will start loading immediately after your page (or in case of ajax loading and constructing HTML image tags afterwards) loads. Hence one 'normal' request that gets processed as it should. If, however, an image src attribute is "undefined", it will then immediately start a get request to "/undefined" route.
hoping someone here can point me in the right direction.
I have a controller Update def running "update_attributes". Currently it returns false, with no error message. I'm fairly new to Ruby, but not to coding, and this has had me stumped for a good few days! I am trying to get the User model and db updated with the values specified below.
def update
#get currently logged in user
#user = current_user
#update user params based on edit form...
if #user.update_attributes(params[:user])
redirect_to profile_path, :notice => "Successfully updated profile."
else
render :action => 'edit'
end
end
my edit def....
def edit
#user = current_user
end
The form sends the following to this update method:
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
utf8: ✓
_method: put
authenticity_token: 9T4ihVI0p8j7pZEFxof3Bfahi2a+o3BPmtXJDnfHT4o=
user: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
first_name: Amanda
last_name: Ross
is_owner: '1'
email: example#googlemail.com
commit: Update
action: update
controller: users
id: '20'
And params[:user] returns:
{"first_name"=>"Amanda", "last_name"=>"Ross", "is_owner"=>"1", "email"=>"example#googlemail.com"}
All these fields are in attr_accessible in the Model, and I can create a user without any problem.
here's development.log output (sorry it's a bit messy)....
Started PUT "/users/20" for 127.0.0.1 at 2012-04-17 10:39:29 +0100
Processing by UsersController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"9T4ihVI0p8j7pZEFxof3Bfahi2a+o3BPmtXJDnfHT4o=", "user"=> {"first_name"=>"Amanda", "last_name"=>"Ross", "is_owner"=>"1", "email"=>"example#googlemail.com"}, "commit"=>"Update", "id"=>"20"}
[1m[36mUser Load (1.0ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = 20 LIMIT 1[0m
>>>>>>>>>>>>
{"first_name"=>"Amanda", "last_name"=>"Ross", "is_owner"=>"1", "email"=>"example#googlemail.com"}
[1m[35m (0.0ms)[0m begin transaction
[1m[36mUser Exists (0.0ms)[0m [1mSELECT 1 FROM "users" WHERE (LOWER("users"."email") = LOWER('example#googlemail.com') AND "users"."id" != 20) LIMIT 1[0m
[1m[35mUser Exists (0.0ms)[0m SELECT 1 FROM "users" WHERE ("users"."email" = 'example#googlemail.com' AND "users"."id" != 20) LIMIT 1
[1m[36m (0.0ms)[0m [1mrollback transaction[0m
Rendered users/_form.html.erb (7.0ms)
Rendered users/edit.html.erb within layouts/application (10.0ms)
Rendered layouts/_includes.html.erb (30.0ms)
Could anyone possibly help point out where I'm going wrong, please?
Thanks in advance!
Both #update_attributes and #save will first check if your model instance is #valid? before continuing on to write to the database. If your model instance is not #valid?, then these methods will return false. To see what's wrong with your model instance, take a look at your model's #errors.
Rails.logger.info(#user.errors.messages.inspect)
Or, embedded in your method,
def update
#user = current_user
if #user.update_attributes(params[:user])
redirect_to profile_path, :notice => "Successfully updated profile."
else
# print the errors to the development log
Rails.logger.info(#user.errors.messages.inspect)
render :action => 'edit'
end
end
You can also get better introspection when updating attributes by calling update_attributes! instead, which raises exceptions instead of just returning false.
I've tried looking at other answers for this but I can't seem to figure out why my redirect isn't working.
So I'm using Devise with Rails 3.1, and I'm making a shopping site. Visitors aren't allowed to add things to their cart unless they are signed in. This is what I'm having trouble with: if they aren't signed in, I want to redirect them to the Items index page. Here's what I have:
class ItemsController < ApplicationController
def add_to_cart
#item = Item.find(params[:id])
if current_user
#item.update_attributes(:cart_id => #current_cart.id)
redirect_to :back
else
redirect_to categories_path, notice: 'You must sign in to add an item to your cart.'
end
end
.
.
.
end
As of right now, when I click the link to add to cart, the method gets executed (I can see Rails loading and defining #item in the server log), and it reaches the 'else' statement, but no redirect happens.
I've already generated scaffolding for the index, new, etc. (all the RESTful actions). Also, I'm sure that I'm reaching the add_to_cart method because I've tried debugging with some puts statements. What's happening here?
EDIT:
Also, another weird thing which may be of use... The server seems to try to execute this method twice, and tries to 'get' categories twice:
Started GET "/items/3/add_to_cart" for 127.0.0.1 at 2012-01-12 16:53:11 -0800
Processing by ItemsController#add_to_cart as JS
Parameters: {"id"=>"3"}
Category Load (0.3ms) SELECT "categories".* FROM "categories"
Item Load (0.2ms) SELECT "items".* FROM "items" WHERE "items"."id" = $1 LIMIT 1 [["id", "3"]]
Redirected to http://localhost:3000/categories
Completed 302 Found in 26ms
Started GET "/items/3/add_to_cart" for 127.0.0.1 at 2012-01-12 16:53:11 -0800
Processing by ItemsController#add_to_cart as JS
Parameters: {"id"=>"3"}
Category Load (0.2ms) SELECT "categories".* FROM "categories"
Item Load (0.2ms) SELECT "items".* FROM "items" WHERE "items"."id" = $1 LIMIT 1 [["id", "3"]]
Redirected to http://localhost:3000/categories
Completed 302 Found in 25ms
Started GET "/categories" for 127.0.0.1 at 2012-01-12 16:53:12 -0800
Processing by CategoriesController#index as JS
Category Load (0.2ms) SELECT "categories".* FROM "categories"
CACHE (0.0ms) SELECT "categories".* FROM "categories"
Rendered categories/index.html.erb within layouts/application (0.0ms)
Completed 200 OK in 35ms (Views: 28.5ms | ActiveRecord: 4.2ms)
Started GET "/categories" for 127.0.0.1 at 2012-01-12 16:53:12 -0800
Processing by CategoriesController#index as JS
Category Load (0.2ms) SELECT "categories".* FROM "categories"
CACHE (0.0ms) SELECT "categories".* FROM "categories"
Rendered categories/index.html.erb within layouts/application (0.0ms)
Completed 200 OK in 37ms (Views: 30.6ms | ActiveRecord: 4.2ms)
EDIT 2 (as requested by Delba)
resources :items do
member do
get 'add_to_cart'
end
end
EDIT 3: changing the else statement to respond to javascript
respond_to do |format|
format.js { redirect_to items_path, notice: 'You must sign in to add an item to your cart.' }
end
For anyone who may need answers to this question, simply replace redirect_to statements with the following:
respond_to do |format|
format.js
end
Then, in your views under items, make a add_to_cart.js.erb page, consisting of javascript to make notices, or do whatever. Here's what I put in mine:
alert("Need to be signed in")
EDIT: Also, for the part where it executes twice: this is somewhat unrelated, but for some reason by default Rails includes duplicate Javascripts. Specifically, look at application.js: it says require jquery and require jquery_ujs. Disable one of these and you're home free.
To disable one of these javascripts:
Go to assets/application.js
Remove the comments (the // ) before require jquery, require tree .
This way, Rails doesn't assume the default and instead includes only jquery and whatever other javascripts you have in assets/javascripts
This is my route:
scope ":username" do
resources :feedbacks
end
So when I go to mydomain.com/test/feedbacks/10 it shows the correct feedback with id=10 that belongs to username=test.
But, if I go to mydomain.com/test2/feedbacks/10 it shows me the same feedback with id=10, which does NOT belong to username=test2.
How do I restrict this from happening?
I am using the Vanity gem to give me the username in the URL, this is what that route looks like:
controller :vanities do
match ':vname' => :show, :via => :get, :constraints => {:vname => /[A-Za-z0-9\-\+\#]+/}
end
Edit 1:
That is to say, for clarity's sake, when I go to mydomain.com/test/feedbacks/10 and /test2/feedbacks/10, it shows me the same view for the same record (in which case, the latter version would be wrong because it should be telling me that no such record exists, but it's not. It is just displaying the correct record for test/feedbacks/10).
Edit 2:
Here are the logs of both requests:
The right request
Started GET "/test-3/feedbacks/7" for 127.0.0.1 at 2011-09-14 02:48:15 -0500
Processing by FeedbacksController#show as HTML
Parameters: {"username"=>"test-3", "id"=>"7"}
Feedback Load (0.5ms) SELECT "feedbacks".* FROM "feedbacks" WHERE "feedbacks"."id" = ? LIMIT 1 [["id", "7"]]
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = 3 LIMIT 1
Rendered feedbacks/show.html.erb within layouts/application (36.2ms)
Completed 200 OK in 188ms (Views: 184.3ms | ActiveRecord: 1.8ms)
The wrong request
Started GET "/test2/feedbacks/7" for 127.0.0.1 at 2011-09-14 02:48:28 -0500
Processing by FeedbacksController#show as HTML
Parameters: {"username"=>"test2", "id"=>"7"}
Feedback Load (0.1ms) SELECT "feedbacks".* FROM "feedbacks" WHERE "feedbacks"."id" = ? LIMIT 1 [["id", "7"]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = 3 LIMIT 1
Rendered feedbacks/show.html.erb within layouts/application (37.6ms)
Completed 200 OK in 50ms (Views: 47.5ms | ActiveRecord: 1.2ms)
Your show action should look something like
def show
#user = User.find_by_username(params[:username])
if #user == current_user
...
render "show"
else
flash[:alert] = "Record doesn't exist"
redirect_to root_path
end
end
I took the liberty of adding in #Benoit's suggestion.
The title pretty much explains it. I'm having an odd situation where views that allow users to delete notifications using Ajax cause the current_user to be logged out. I don't even know where to begin debugging this...
Here's the controller
class NotificationsController < ApplicationController
def destroy
#notification = Notification.find(params[:id])
#notification.destroy
respond_to do |format|
format.js
end
end
end
This is the entire controller, nothing is abridged. The notifications are generated by the system, so the only action a user can take is to "dismiss" (ie. delete) them.
I also tried this using the newer respond_with syntax and had the same effect.
I'm using Devise, and Rails 3.0.9. Any idea what could be going on -- or suggestions on how to debug??
-- EDIT 1 --
Routes.rb
resources :notifications, :only => [:destroy]
Delete link
%span.delete= link_to( 'dismiss', notification_path(notification), :method => :delete, :remote => true )
-- EDIT 2 --
Well, I noticed something new in the logs -- see **** below.
Started DELETE "/notifications/10" for 127.0.0.1 at 2011-06-21 21:47:15 -0500
Processing by NotificationsController#destroy as JS
Parameters: {"id"=>"10"}
SQL (0.4ms) SELECT name
FROM sqlite_master
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
SQL (0.3ms) SELECT name
FROM sqlite_master
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
Slug Load (0.4ms) SELECT "slugs".* FROM "slugs" WHERE ("slugs".sluggable_id = 1 AND "slugs".sluggable_type = 'User') ORDER BY id DESC LIMIT 1
****AREL (0.3ms) UPDATE "users" SET "remember_token" = NULL, "remember_created_at" = NULL, "updated_at" = '2011-06-22 02:47:15.913839', "preferences" = '---
:email_notifications: ''true''
' WHERE "users"."id" = 1
Notification Load (0.2ms) SELECT "notifications".* FROM "notifications" WHERE "notifications"."id" = 10 LIMIT 1
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
AREL (0.3ms) UPDATE "users" SET "notifications_count" = COALESCE("notifications_count", 0) - 1 WHERE "users"."id" = 1
AREL (0.1ms) DELETE FROM "notifications" WHERE "notifications"."id" = 10
Rendered notifications/destroy.js.erb (0.7ms)
Completed 200 OK in 6416ms (Views: 9.6ms | ActiveRecord: 4.1ms)
So, there it is, it looks like part of the users table is getting set to null, particularly the remember_token which I suspect is triggering Devise to end the session, or maybe this is done by Devise after the session is destroyed. But how do I track that down?
The only thing I can think of that causes notifications to interact with Users is there's a counter_cache on Users for notifications_count.
I appreciate thoughts and suggestions on how to debug!
-- EDIT 3 --
After digging with ruby-debug it looks like the issue is related to Devise and changes to the rails.js script. See:
https://github.com/plataformatec/devise/issues/913
https://github.com/ryanb/cancan/issues/280
I'm trying out some of the suggestions on those threads and will post if I find a solution.
I had a similar problem. Solution was as simple as adding
<%= csrf_meta_tag %>
to the layout.
It turns out this had to do with changes to the Rails jQuery UJS driver and Devise. I had updated Devise without updating jQuery UJS -- and Devise was expecting the CSRF token to be handled differently, so it was processing the ajax request as unauthorized which meant destroying the current user's session. Upgrading to the latest jQuery Rails driver fixed the problem.
Are you sure this controller and action are the ones that are triggered by the request? It sounds like the path you are DELETEing isnt right and you are hitting your sessions path instead.
Is it possible that the destroy notification path is redirecting to the session destroy path through JS?
Do you have destroy.js template in your notifications views? try adding one that is empty see if you get a different result.