update action not saving data - ruby-on-rails-3

I am having trouble getting a form text area to update a field in a rails 3.0.8 app. I keep stripping out as much as i can to narrow down where the error lies. Here's what is left.
My form:
<%= form_for #fb_comments, :remote => true, :html => { :'data-type' => 'html', :id => 'comment' } do |form| %>
<%= form.text_area :comment %>
<%= form.submit "Update Comments" %>
<% end %>
The dummy data that i put into the comment column via mysql for this record shows up so the current data is making it to the form.
controller:
def update
fbc = FbComments.find(params[:id])
fbc.update_attributes(params[:comment])
...
end
console message:
Started POST "/fb_comments/1" for 127.0.0.1 at 2011-06-13 17:31:43 -0400
Processing by FbCommentsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"gLA2A11uVRl/WtIR1p90aSkLoU6b8twotK+B1YNefRk=", "fb_comments"=>{"comment"=>"test test"}, "commit"=>"Update Comments", "id"=>"1"}
FbComments Load (0.1ms) SELECT `fb_comments`.* FROM `fb_comments` WHERE `fb_comments`.`id` = 1 LIMIT 1
SQL (0.1ms) BEGIN
SQL (0.1ms) COMMIT
Rendered text template (0.0ms)
Completed 200 OK in 15ms (Views: 0.6ms | ActiveRecord: 0.3ms)
Thanks.

Your controller is recieving fb_comments not comment:
fbc.update_attributes(params[:fb_comments])
Hoe this helps.

Related

Invalid Form Entry Causes Authlogic to Rollback to a Different Form

(Using Rails 3) I have authlogic set up to manage my users and user sessions (with a user controller and user_sessions controller and associated views, models, etc). I have two levels of user: an admin and a client. The admin can create users and edit users, and users are only able to look at documents on the website (no user editing or viewing privileges at all).
Then I implemented another controller (reset_password) which allows clients to change their password on the website. To do this I allowed clients to edit clients (so they can edit themselves). But The form that allows clients to change their password is much more limited than the form that allows admins to make clients.
The problem I am having is that when a client goes to the password editing form, and enters an invalid password or password confirmation, the page refreshes to the full admin form that lets clients change their privileges, etc. What I need is a way to force a failed form entry to return the client to the same form that they were just on rather than the admin form.
The problem, I am pretty sure, is because both the admin form and the client form use 'form_for #user do |f|' to define the form. I believe that rails cannot tell the two apart.
Here are the relevant files:
My admin form (users#edit with rendered form):
= stylesheet_link_tag :universal
= form_for #user do |f|
- if #user.errors.any?
#error_explanation
%span.boldHeader= "#{pluralize(#user.errors.count, "error")} prohibited this user from being saved:"
%ul
- #user.errors.full_messages.each do |msg|
%li= msg
.fieldContainer
.field
= f.label :username
= f.text_field :username
.field
= f.label :role
= f.collection_select :role, User::ROLES, :to_s, :humanize, { :selected => :client }
.fieldContainer
.field
= f.label :password
= f.password_field :password
.field
= f.label :password_confirmation
= f.password_field :password_confirmation
.fieldContainer
.field
= f.label :first_name
= f.text_field :first_name
.field
= f.label :last_name
= f.text_field :last_name
.field
= f.label :firm_name
= f.text_field :firm_name
.fieldContainer
.field
= f.label :email
= f.text_field :email
.field
= f.label :phone
= f.text_field :phone
.actions
= f.submit 'Save'
%a.button{ :href => "/users" }Cancel
My client form (reset_password#edit with rendered form):
= stylesheet_link_tag :universal
= form_for #user do |f|
- if #user.errors.any?
#error_explanation
%span.boldHeader= "#{pluralize(#user.errors.count, "error")} prohibited this user from being saved:"
%ul
- #user.errors.full_messages.each do |msg|
%li= msg
.fieldContainer
.field
= f.label :password
= f.password_field :password
.field
= f.label :password_confirmation
= f.password_field :password_confirmation
.actions
= f.submit 'Save'
%a.button{ :href => "/users" }Cancel
Client form update method:
def update
#user = current_user
if #user.update_attributes(params[:user])
format.html { redirect_to #user, notice: 'Password successfully changed.' }
format.json { head :no_content }
else
format.json { render json: #user.errors, status: :unprocessable_entity }
format.html { redirect_to "/settings" }
end
end
Admin form update method:
def update
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to #user, notice: 'User was successfully updated' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
Note: /settings routes to reset_passwords#edit which has a partial render in it which is how I display the client form (see above). I also have users, user_sessions, and reset_passwords as resources in my routes file.
Finally, here is what I am seeing in the production log. You can see that I start in reset_password/_form (the client form) but then I get rolled back to users/_form (the admin form).
Started GET "/settings" for 127.0.0.1 at 2013-07-02 16:26:52 -0400
Processing by ResetPasswordsController#edit as HTML
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
Rendered reset_passwords/_form.html.haml (4.0ms)
Rendered reset_passwords/edit.html.haml within layouts/application (14.0ms)
Rendered shared/_header.html.haml (1.0ms)
Completed 200 OK in 57ms (Views: 54.0ms | ActiveRecord: 0.0ms)
[2013-07-02 16:26:52] WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
Started GET "/assets/global.css?body=1" for 127.0.0.1 at 2013-07-02 16:26:52 -0400
Served asset /global.css - 304 Not Modified (0ms)
[2013-07-02 16:26:53] WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
Started PUT "/users/1" for 127.0.0.1 at 2013-07-02 16:26:58 -0400
Processing by UsersController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"9KeHrOySL3FRhSnfYtVvKl2rCz9EPBSyGmtGGasDxnA=", "user"=>{"password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Save", "id"=>"1"}
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", "1"]]
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
(0.0ms) begin transaction
User Exists (0.0ms) SELECT 1 AS one FROM "users" WHERE ("users"."persistence_token" = '5d1007bf94b34a7de44707e4ca432b18338f1c9ef6c5f99bf04845096a6b880057b5b43c917b9d38f790521ef62147eec3d9302471da73967048b48b4a399b18' AND "users"."id" != 1) LIMIT 1
(1.0ms) rollback transaction
Rendered users/_form.html.haml (9.0ms)
Rendered users/edit.html.haml within layouts/application (19.0ms)
Rendered shared/_header.html.haml (0.0ms)
Completed 200 OK in 80ms (Views: 61.0ms | ActiveRecord: 1.0ms)
I needed to specify the route for the form to take. Previously I had this in my "client" form (reset_password#edit with rendered form):
= form_for #user do |f|
I changed this to the following:
= form_for #user, :url => reset_password_path(#user) do |f|
I then also made some changes to the controller for the form:
def update
#user = current_user
#user.password = params[:user][:password]
#user.password_confirmation = params[:user][:password_confirmation]
respond_to do |format|
if !#user.changed?
format.html { redirect_to "/settings", notice: 'Form incomplete' }
format.json { render json: #user.errors, status: :unprocessable_entity }
elsif #user.save
format.html { redirect_to "/index", notice: 'Password successfully changed' }
format.json { head :no_content }
else
format.html { redirect_to "/settings", notice: 'Form incomplete' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
The part that I needed was the respond_to do |format|, the rest are just some logic changes to make it work better for my application.

Rails AJAX request 500 Internal Server Error details

I have a form partial as follows:
_internet_service_form.html.erb
<%= simple_form_for #internet_service, remote: true do |f| %>
<%= f.input :start_date %>
<%= f.button :submit %>
<% end %>
When I render it in the new action of the controller, it returns a 500 internal server with no further explanation.
When I render it in the edit action of the controller, it renders correctly.
If I replace the partial with a text block with no rails tags in it, it renders correctly, so I know it's not a routing error.
new.js.erb
$("#result-content").html("<%= escape_javascript(render(partial: 'new')) %>");
new.html.erb
<%= render partial: 'internet_service_form' %>
internet_service_controller.rb
def new
#internet_service = InternetService.new
end
def edit
#internet_service = InternetService.find(params[:id])
end
These actions are being performed through AJAX, and the most useful logs I'm getting out of the development log are:
Started POST "/accounts/29/internet_services/new.js" for 10.12.68.100 at 2013-02-13 00:28:11 +1300
Processing by InternetServicesController#new as JS
... snip ...
Rendered internet_services/_internet_service_form.html.erb (14.9ms)
Rendered internet_services/_new.html.erb (24.3ms)
Rendered internet_services/new.js.erb (32.2ms)
Completed 500 Internal Server Error in 231ms

"stack level too deep" error in show#controller for nested forms

I get an
SystemStackError in Admin::ChecklistsController#show
stack level too deep
The Controller Action:
# GET /admin/checklists/1
# GET /admin/checklists/1.json
def show
#admin_checklist = Admin::Checklist.find(params[:id])
respond_to do |format|
format.html #show.html.erb
format.json { render json: #admin_checklist }
end
end
And the models
class Admin::Checklist < ActiveRecord::Base
attr_accessible :description, :name, :usable, :categories_attributes
has_many :categories, :dependent => :destroy
validates_presence_of :name,:description
accepts_nested_attributes_for :categories, :allow_destroy => true
end
class Admin::Category < ActiveRecord::Base
attr_accessible :export_head, :export_position, :export_text, :frontend_head, :frontend_position, :frontend_text
belongs_to :checklist
validates_presence_of :frontend_head, :frontend_text
end
I already played around a bit with the attributes_accessible. If I replace :categories_attributes by :categories
Then I loose the endless loop error, but as expected, I can't mass-assign any category attributes anymore
Anyone got an idea how i can fix both errors.
EDIT:
Started GET "/admin/checklists/4" for 192.168.4.191 at 2012-12-12
10:12:41 +0100 Processing by Admin::ChecklistsController#show as HTML
Parameters: {"id"=>"4"} Admin::Checklist Load (0.2ms) SELECT
"admin_checklists".* FROM "admin_checkli
sts" WHERE "admin_checklists"."id" = ? LIMIT 1 [["id", "4"]] CACHE
(0.0ms) SELECT "admin_checklists".* FROM "admin_checklists" WHERE
"admi
n_checklists"."id" = ? LIMIT 1 [["id", "4"]] Completed 500 Internal
Server Error in 240ms
SystemStackError (stack level too deep): actionpack (3.2.9)
lib/action_dispatch/middleware/reloader.rb:70
Rendered
/var/lib/gems/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middlew
are/templates/rescues/_trace.erb (1.5ms) Rendered
/var/lib/gems/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middlew
are/templates/rescues/_request_and_response.erb (1.3ms) Rendered
/var/lib/gems/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middlew
are/templates/rescues/diagnostics.erb within rescues/layout (10.7ms)
I get this SQL-Staement about 100 times for each Page request. This seems to be some bug in active record or miss-usage by me of active record for nested models .....
Edit2:
irb(main):001:0> Admin::Checklist.find('4') Admin::Checklist Load
(0.2ms) SELECT "admin_checklists".* FROM "admin_checkli
sts" WHERE "admin_checklists"."id" = ? LIMIT 1 [["id", "4"]]
=> #
BrummliBrummliBrummliBrummliBrummliBrummliBr...", usable: false,
created_at: "20 12-12-11 13:43:23",
updated_at: "2012-12-11 13:43:23">
Funny fact it now works and I'm not quite sure what really fixed it, because i changed nothing. I just came back from my break. Did the find on the console. Checked it in the template again and i got a different error message belonging to a malformed loop, because i had removed it again, which i fixed by pasting the removed part in again.
<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= #admin_checklist.name %>
</p>
<p>
<b>Description:</b>
<%= #admin_checklist.description %>
</p>
<p>
<b>Usable:</b>
<%= #admin_checklist.usable %>
</p>
<p>
<ul>
<% #admin_checklist.categories.each do |category|%>
<li>
<h3><%= category.frontend_head %></h3>
<p><%= category.frontend_text %></p>
</li>
<% end %>
</ul>
</p>
<%= link_to 'Edit', edit_admin_checklist_path(#admin_checklist) %> |
<%= link_to 'Back', admin_checklists_path %>
I'm sorry I can't provide an answer why this happened.

storing complex records in rails database with form_tag

I'm trying to save records in a database. Many of the column values will be taken from a http request to an api.
I have a text field and some check boxes along with the session_id in the form which will be persisted. this is posted from another controller (form_tag('results#store'))to an action called store in the results controller.
Store action:
def store
query = query_preprocesser(params[:query]) # this is in a helper
## example of resArray ##
#resArray = [[{:engine => "bing, :results => [{:Description => "abc", :Title => "def"}, {:Description => "ghi", :Title => "jkl"}]}, {etc},{etc} ],[{:eng...}]]
resArray = getResults(query) # Also a helper method returning an array of up to 3 arrays
resArray.each do |engine|
db_name = engine[:engine]
engine[:results].each do |set|
res = Result.new(
:session_id => params[:session_id],
:db_name => db_name,
:query => query,
:rank => set[:Rank],
:description => set[:Description],
:title => set[:Title],
:url => set[:Url] )
res.save!
end
end
res.each do |res|
res.save
end
#Result.new(:session_id => params[:session_id], :db_name => "Bing", :query => "Whats the story", :query_rank => 1, :title => "The Title", :description => "descript", :url => "www.google.ie",:query_number => 1)
respond_to do |format|
format.html { redirect_to pages_path }
format.json { head :no_content }
end
end
My routes are resources :results
Server logs:
[2012-07-10 23:30:48] INFO WEBrick 1.3.1
[2012-07-10 23:30:48] INFO ruby 1.9.3 (2012-04-20) [x86_64-linux]
[2012-07-10 23:30:48] INFO WEBrick::HTTPServer#start: pid=15584 port=3000
Started POST "/results" for 127.0.0.1 at 2012-07-10 23:31:36 +0100
Connecting to database specified by database.yml
Processing by ResultsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"/nTJOF5Ab+XnL+jxRBHnTJz45YRVmgbf55bmn5/iz8E=", "query"=>"search term", "button"=>"", "searchType"=>"Seperate", "bing"=>"1", "session_id"=>"e08c13a99f21a91520fcc393e0860c94"}
(0.2ms) begin transaction
(0.2ms) rollback transaction
Rendered results/_form.html.erb (13.9ms)
Rendered results/new.html.erb within layouts/application (23.6ms)
Completed 200 OK in 213ms (Views: 78.4ms | ActiveRecord: 2.9ms)
Form:
<%= form_tag('results#store') do %>
Rake routes:
store POST /pages(.:format) results#store
results GET /results(.:format) results#index
POST /results(.:format) results#create
new_result GET /results/new(.:format) results#new
edit_result GET /results/:id/edit(.:format) results#edit
result GET /results/:id(.:format) results#show
PUT /results/:id(.:format) results#update
DELETE /results/:id(.:format) results#destroy
store POST /pages(.:format) results#store
pages GET /pages(.:format) pages#index
I keep getting redirected to the new action in Results controller. The helper methods aren't even being executed. I'm a past master at over complicating things, can anyone help unravel this for me?
Do you have a route set up for the store action? If you do then you should use the url helper for it in your form tag:
form_tag( results_store_url )

Rails properly pass in id through form

I just need some clarity of thought on this one. I've got a Photos show page where a user can click "Like" to create a new like record for a particular photo.
On my photos show.html page I have the following form:
<%= form_for :like, :url => likes_path do |f| %>
<%= hidden_field_tag(:photo_id, #photo.id) %>
<%= f.submit "Like" %>
<% end %>
When I click the form I get a message that it "Couldn't find a Photo without an ID":
Started POST "/likes" for 127.0.0.1 at Sat Feb 25 16:43:21 -0500 2012
Processing by LikesController#create as HTML
Parameters: {"commit"=>"Like", "authenticity_token"=>"cQnuAHb/f6Sgo3aB5xPKErx3joQTV+DHGs0w9vi13vM=", "utf8"=>"\342\234\223", "photo_id"=>"47"}
Completed 404 Not Found in 68ms
ActiveRecord::RecordNotFound (Couldn't find Photo without an ID):
app/controllers/likes_controller.rb:8:in `create'
Not sure why when it seems to be passing in the photo_id correctly, no?
Here's a look at my likes_controller:
def create
#photo = Photo.find(params[:id])
#like = Like.new(:photo_id => :photo_id, :user_id => current_user.id)
end
Anyone see what I'm doing wrong here? Thanks.
It should work with Photo.find(params[:photo_id]).
The error message says that you called Photo.findwith a nil parameter, e.g. there is no parameter id in the request.