I have a Opportunity Model that has many Links. Links is a nested resource of Opportunity. On my views/opportunities/show.html.erb page, I display all the links that belong to that opportunity and I rendered a "new link" form as well. This form worked fine until recently and I am not sure why. When I fill out the "new link" form and click "add", the record does not save. Could someone please help me with this?
Here is my views/opportunities/show.html.erb page:
<%= render #opportunity %>
<form>
<fieldset>
<legend>Links</legend>
<div id="links">
<%= render #opportunity.links %>
</div>
<%= render :file => 'links/new' %>
</fieldset>
</form>
Here is my views/links/new page:
<%= form_for ([#opportunity, #opportunity.links.new]) do |f| %>
<div class="field">
<%= f.label "Description:" %> <br />
<%= f.text_field :description %>
</div>
<div class="field">
<%= f.label "URL:" %> <br />
<%= f.text_field :link_url %>
</div>
<div class="actions">
<%= f.submit 'Add' %>
</div>
<% end %>
Here is my create link controller:
def create
#opportunity = Opportunity.find(params[:opportunity_id])
#link = #opportunity.links.new(link_params)
if #link.save
redirect_to #opportunity, notice: 'link has been added'
else
redirect_to #opportunity, alert: 'Unable to add link'
end
end
Here is my Link model:
class Link < ActiveRecord::Base
belongs_to :opportunity
end
Here is my Opportunity model:
class Opportunity < ActiveRecord::Base
has_many :links
end
Here is the code from my console:
Started GET "/opportunities/7?utf8=%E2%9C%93&authenticity_token=ZLgPz98w2MjTChzzDXJ8EcqNmYNtBUG5DSYcp1CXReU%3D&link%5Bdescription%5D=testlink&link%5Blink_url%5D=testlink&commit=Add" for 127.0.0.1 at 2014-06-02 15:19:06 -0400
Processing by OpportunitiesController#show as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ZLgPz98w2MjTChzzDXJ8EcqNmYNtBUG5DSYcp1CXReU=", "link"=>{"description"=>"testlink", "link_url"=>"testlink"}, "commit"=>"Add", "id"=>"7"}
Opportunity Load (0.2ms) SELECT "opportunities".* FROM "opportunities" WHERE "opportunities"."id" = ? LIMIT 1 [["id", 7]]
Rendered opportunities/_opportunity.html.erb (2.0ms)
Link Load (0.1ms) SELECT "links".* FROM "links" WHERE "links"."opportunity_id" = ? [["opportunity_id", 7]]
Rendered links/_link.html.erb (0.2ms)
Rendered links/new.html.erb (2.0ms)
Well, you need to debug it. I would start with adding the gem pry to your project.
Then you should temporarily change your code to something like:
def create
#opportunity = Opportunity.find(params[:opportunity_id])
#link = #opportunity.links.new(link_params)
if #link.save
redirect_to #opportunity, notice: 'link has been added'
else
binding.pry
redirect_to #opportunity, alert: 'Unable to add link'
end
end
In order to test it, you perform the add link action as usual. The code processing will stop at the line where binding.pry is being called. I assume here that the saving of therecord fails and we enter else part of the condition.
If I assume correctly, the link variable will be enriched with errors. In the console prompt of binding.pry just try to display them, if there are any (#link.errors)
I hope that helps.
Related
I am trying to save data, but on submitting the data, it just refreshes the page, but not actually stores data in table. and even it is not giving any errors too. What I want to do is after saving data, control should come on same page with empty textboxes.
Using Ruby 2.4.1, Rails 5.1.3, sqLite3
This is content of feedback_controller.rb
class FeedbackController < ApplicationController
def new
#feedback = Feedback.new
end
def create
#feedback = Feedback.new(feedback_params)
redirect_to root_path
respond_to do |f|
if #feedback.save
f.html {redirect_to #feedback, notice: 'feedback submitted'}
f.json {render :new, status: :created, location: :#feedback}
else
f.html {render :new }
f.json {render json: #feedback.errors, status: :unprocessable_entity}
end
end
end
private
# def set_feedback
# #feedback = Feedback.find(params[:id])
# end
def feedback_params
params.require(:feedback).permit(:name, :email, :message)
end
end
And here is new.html.erb file.
<%= form_with scope: :feedback, url: feedback_new_path, local: true do |form| %>
<% if #feedback.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(feedback.errors.count, "error") %> prohibited this feedback from being saved:</h2>
<ul>
<% #feedback.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name, id: :feedback_name %>
</div>
<div class="field">
<%= form.label :email %>
<%= form.text_field :email, id: :feedback_email %>
</div>
<div class="field">
<%= form.label :message %>
<%= form.text_area :message, id: :feedback_message %>
</div>
<div class="actions">
<%= form.submit "Submit Feedback"%>
</div>
<% end %>
<%= link_to 'Home', root_path %>
This is what puma server saying on log while storing data:
Started POST "/feedback/new" for 127.0.0.1 at 2017-09-14 21:33:41 +0530
Processing by FeedbackController#new as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Dk1sGiKYryIOeU6HyO7zeX6wqXazj9BUfooJgIDH1JjHxuKwA5MT0E6zvuwFYXGA8xEOz+tGAiXWySKv7voKvg==", "feedback"=>{"name"=>"sheshang", "email"=>"sid#gm.co", "message"=>"this is demo message"}, "commit"=>"Submit Feedback"}
Rendering feedback/new.html.erb within layouts/application
Rendered feedback/new.html.erb within layouts/application (3.8ms)
Completed 200 OK in 75ms (Views: 55.2ms | ActiveRecord: 1.3ms)
In addition to this problem, I want to know that how to debug in rails app. Like in C or any other program we used to put printf statements to check whether the control is going inside or not. How we can do in Rails?
As you can see, you're posting to the new action:
Started POST "/feedback/new" for 127.0.0.1 at 2017-09-14 21:33:41 +0530
Processing by FeedbackController#new as HTML
But the new action doesn't do a save.
So, you probably want:
<%= form_with scope: :feedback, url: feedbacks_path, local: true do |form| %>
By convention, if you do (in your routes.rb file):
resources :feedbacks
then you should get:
feedbacks GET /feedbacks(.:format) feedbacks#index
POST /feedbacks(.:format) feedbacks#create
new_feedback GET /feedbacks/new(.:format) feedbacks#new
edit_feedback GET /feedbacks/:id/edit(.:format) feedbacks#edit
feedback GET /feedbacks/:id(.:format) feedbacks#show
PATCH /feedbacks/:id(.:format) feedbacks#update
PUT /feedbacks/:id(.:format) feedbacks#update
DELETE /feedbacks/:id(.:format) feedbacks#destroy
As you can see, this does not generate a POST verb for the new action, which suggests that you're not using conventional routes. If that is true, then you may need to update your routes so that you get feedbacks_path.
I recommend following convention as it often makes life easier.
As far as printing to console, I tend to do:
puts "#{self.class}.#{__method__}, var: #{var}"
I replace var with whatever variable I want to inspect. I like to include the #{self.class}.#{__method__} bit because it let's me know which class and method I'm in.
I have the following structure in my app:
resources :workouts do
resources :exercises
end
A workout has_many exercises. I have it displayed so that on the workouts#show page there is a link to the exercises#index page to add/edit the exercises that belong to that workout. On the exercises#index page the list of exercises populates properly, but when I try to delete an exercise it gives me this error: Couldn't find Exercise with 'id'=10 [WHERE "exercises"."workout_id" = ?]
My exercises#index page is:
<div class="container col-sm-10 col-sm-push-1" style="margin-top: 100px">
<div class="opaque-card md-well well">
<h1>Current Exercises:</h1>
<% #exercises.each do |exercise| %>
<p><%= exercise.name %> (<%= link_to "Delete #{exercise.name}", workout_exercise_path(#workout, exercise), method: :delete, data: { confirm: 'Are you sure?' } %>)</p>
<% end %>
<h1>Add New Exercises:</h1>
<%= render 'exercises/form' %>
</div> <!-- opaque card -->
</div> <!-- container -->
My corresponding routes are:
workout_exercises GET /workouts/:workout_id/exercises(.:format) exercises#index
POST /workouts/:workout_id/exercises(.:format) exercises#create
new_workout_exercise GET /workouts/:workout_id/exercises/new(.:format) exercises#new
edit_workout_exercise GET /workouts/:workout_id/exercises/:id/edit(.:format) exercises#edit
workout_exercise GET /workouts/:workout_id/exercises/:id(.:format) exercises#show
PATCH /workouts/:workout_id/exercises/:id(.:format) exercises#update
PUT /workouts/:workout_id/exercises/:id(.:format) exercises#update
DELETE /workouts/:workout_id/exercises/:id(.:format) exercises#destroy
workouts GET /workouts(.:format) workouts#index
POST /workouts(.:format) workouts#create
new_workout GET /workouts/new(.:format) workouts#new
edit_workout GET /workouts/:id/edit(.:format) workouts#edit
workout GET /workouts/:id(.:format) workouts#show
PATCH /workouts/:id(.:format) workouts#update
PUT /workouts/:id(.:format) workouts#update
DELETE /workouts/:id(.:format) workouts#destroy
And here is my exercises_controller.rb:
class ExercisesController < ApplicationController
before_action :authenticate_user!
def index
#workout = Workout.friendly.find(params[:workout_id])
#exercise = Exercise.new
#exercises = Exercise.all
end
def new
#workout = Workout.friendly.find(params[:id])
#exercise = Exercise.new
end
def create
# require 'pry' ; binding.pry
#workout = Workout.friendly.find(params[:workout_id])
exercise = #workout.exercises.build(exercise_params)
exercise.user = current_user
if exercise.save
flash[:notice] = "Exercise created successfully."
redirect_to [#workout]
else
flash[:alert] = "The exercise failed to save."
redirect_to [#workout]
end
end
def edit
#workout = Workout.friendly.find(params[:id])
exercise = Exercise.find(params[:id])
exercise.user = current_user
end
def destroy
#workout = Workout.friendly.find(params[:workout_id])
exercise = #workout.exercises.find(params[:id])
if exercise.destroy
flash[:notice] = "Exercise was deleted successfully."
redirect_to [#workout]
else
flash[:alert] = "Exercise couldn't be deleted. Try again."
redirect_to [#workout]
end
end
private
def exercise_params
params.require(:exercise).permit(:name, :needs_seconds, :needs_weight, :needs_reps, :workout_id)
end
def authorize_user
exercise = Exercise.find(params[:id])
unless current_user == current_user.admin?
flash[:alert] = "You do not have permission to create or delete an exercise."
redirect_to [exercise.workout]
end
end
end
I have already tried un-nesting the routes and that causes far more errors than it resolves. Can anyone see why I'm getting this error or how to fix it?
ADDED: Here are the params from my server log from before the error:
Started DELETE "/workouts/d/exercises/10" for ::1 at 2016-06-05 10:39:29 -0700
Processing by ExercisesController#destroy as HTML
Parameters: {"authenticity_token"=>"xAWbVPHRNJeGSWhThaAMDf/FUYXav4WXrMBnjoX7s3g+gTQEVo0r9wIhSxIB+yH8sdwhcxfDZV9SinaLSUEiMA==", "workout_id"=>"d", "id"=>"10"}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Workout Load (0.1ms) SELECT "workouts".* FROM "workouts" WHERE "workouts"."slug" = ? ORDER BY "workouts"."id" ASC LIMIT 1 [["slug", "d"]]
Exercise Load (0.2ms) SELECT "exercises".* FROM "exercises" WHERE "exercises"."workout_id" = ? AND "exercises"."id" = ? LIMIT 1 [["workout_id", 4], ["id", 10]]
Completed 404 Not Found in 6ms (ActiveRecord: 0.4ms)
ActiveRecord::RecordNotFound - Couldn't find Exercise with 'id'=10 [WHERE "exercises"."workout_id" = ?]:
ADDED: Form referenced in exercises#index:
<div class="row">
<div class="col-xs-10 col-xs-push-1">
<%= form_for [#workout, #exercise] do |f| %>
<%= f.hidden_field :workout_id, value: #workout.id %>
<div class="form-group">
<%= f.label :name, class: 'sr-only' %>
<%= f.text_field :name, class: 'form-control', placeholder: "Enter exercise name" %>
</div>
<div class="form-group col-xs-4">
<p><%= f.label :needs_seconds, class: 'sr-only' %>
<%= f.check_box :needs_seconds, class: 'check_box' %> Report seconds?</p>
</div>
<div class="form-group col-xs-4">
<p><%= f.label :needs_reps, class: 'sr-only' %>
<%= f.check_box :needs_reps, class: 'check_box' %> Report reps?</p>
</div>
<div class="form-group col-xs-4">
<p><%= f.label :needs_weight, class: 'sr-only' %>
<%= f.check_box :needs_weight, class: 'check_box' %> Report weight?</p>
</div>
<div class="text-center"><%= f.submit "Create Exercise", class: 'btn btn-primary' %></div>
<% end %>
</div>
</div>
I think the problem is Workout.friendly.find(params[:workout_id]) is not finding any records. Can you make sure it does find something, by printing it out to the rails console,
#workout = Workout.friendly.find(params[:workout_id])
exercise = #workout.exercises.find(params[:id])
p "Workout: ", #workout
p "Exercise: ", exercise #they should print the found object or nil in your rails server console
If you see nil I'd say finding via friendly id is causing the problem.
Update:
My bad. I hadn't seen. So see when you're building your exercise you're passing exercise_params, and if you note exercise_params also has a workout_id which must be passed nil so it rewrites the value of workout_id in your newly created exercise. Just get rid of workout_id from your exercise params. And try creating a few more exersize and test again for those.
ActiveRecord::RecordNotFound - Couldn't find Exercise with 'id'=10
[WHERE "exercises"."workout_id" = ?]
There are two problems in your code. First the #exercises variable holds all the exercises records not the #workout's exercises. Second, with the exercise variable you are trying to find that workout's exercise with the params[:id] which is actually the id of one of the #exercises looped in the view. So Rails unable to find the record with the combination(:workout_id & :id), so is the error.
Solution
Change exercise = #workout.exercises.find(params[:id]) to exercise = Exercise.find(params[:id]) in the destroy method.
def destroy
#workout = Workout.friendly.find(params[:workout_id])
exercise = Exercise.find(params[:id])
if exercise.destroy
flash[:notice] = "Exercise was deleted successfully."
redirect_to [#workout]
else
flash[:alert] = "Exercise couldn't be deleted. Try again."
redirect_to [#workout]
end
end
I'm trying to save a form, and I am so lost on why it refuses to save. Does anybod have a clue what might be wrong?
Here's the form code:
<%= form_for #service, url: services_path do |f| %>
<% #profiles.each do |profile| %>
<%= f.text_field :service_id, value: "#{profile.service_id}" %>
<div class="media">
<a class="media-left" href="#">
<%= image_tag profile.avatar, height: '45', width: '45', class: 'img-circle' %>
</a>
<div class="media-body">
<h4 class="media-heading"><%= profile.service_username %></h4>
<%= profile.service %>
</div>
</div>
<% end %>
<%= f.submit %>
<% end %>
and
#service = current_user.services.new
the association between them are:
user has_many :services
service belongs_to :user
and the services controller create looks like this:
def create
#service = current_user.services.new(service_params)
if #service.save
flash[:notice] = "success"
redirect_to root_url
else
flash[:alert] = "Unable to add"
redirect_to :back
end
end
my logs say:
Started POST "/services" for 127.0.0.1 at 2015-01-17 18:09:44 -0800
Processing by ServicesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"lsW5aVuVUCQrHsaCo+uxbR11sF3mph3lTnM8O/Dtxn8=", "service"=> {"service_id"=>"2967861508"}, "commit"=>"Create Service"}
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = 30 ORDER BY "users"."id" ASC LIMIT 1
(0.2ms) BEGIN
(0.2ms) ROLLBACK
Redirected to http://localhost:3000/schedules
Completed 302 Found in 9ms (ActiveRecord: 1.1ms)
Oops, minor edit below (#service.errors instead of #validation.errors):
From your logs, you can see that you got into the controller create method and the save failed. This is usually a validation problem but I can't tell from what you posted. I would put #service.errors into the flash instead of just "unable to add". This should help you and future users see what's going on when the create fails.
I have Realization model:
# encoding : utf-8
class Realization < ActiveRecord::Base
attr_accessible :city, :street, :title, :work, :photo, :date
has_attached_file :photo
end
Controller:
# encoding : utf-8
class RealizationsController < ApplicationController
before_filter :admin_required, :except => [:index,:show]
# GET /realization/new
def new
#realization = Realization.new
#realization.date = Time.now.__send__(:to_date).to_s
end
# POST /realization
def create
#realization = Realization.new(params[:realization])
if #realization.save
redirect_to #realization, notice: 'realization was successfully created.'
else
render action: "new"
end
end
(...) others
View of form:
<%= form_for #realization, :html => { :multipart => true } do |f| %>
<% if #realization.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#realization.errors.count, "error") %> prohibited this realization from being saved:</h2>
<ul>
<% #realization.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
(...)
<div class="field">
<%= f.file_field :photo %>
</div>
<div class="actions">
<%= f.submit "Submit" %>
</div>
<% end %>
And routes :
resources :realizations
And WEBrick server info is that:
Started POST "/realizacje" for 127.0.0.1 at 2013-04-12 12:26:35 +0200
Processing by RealizationsController#index as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"zK5jP4ChBBY+R21TjrZkp4xGvCHViTFJ+8Fw6Og28YY=", "realization"=>{"title"=>"wwwwww", "street"=>"", "city"=>"", "work"=>"", "date"=>"2013-04-12"}, "commit"=>"Submit"}
(1.0ms) SELECT COUNT(*) FROM "realizations"
Realization Load (2.0ms) SELECT "realizations".* FROM "realizations" ORDER BY created_at DESC LIMIT 7 OFFSET 0
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
Rendered realizations/index.html.erb within layouts/application (156.0ms)
Completed 200 OK in 340ms (Views: 333.0ms | ActiveRecord: 4.0ms)
While I use the form and push the submit it redirects/randers realizations/index without notice or errors even!
I have completely no idea why? Especialy that it worked before...
Maybe javascript added later on may be the reason?
Paperclip works well in update so it isn't it...
You might check your new action to see what you're passing in to the form_for.
You want to be passing in a brand new instance of your Realization model.
i.e. in the new action you should have a line that reads #realization = Realization.new
The reason I suggest this is because form_for calls a method (#new_record?) on the object you give it and will submit a post or put request depending on whether that method call returns true or false.
I'm trying to display errors messages in my ajax form (the code is based on this question):
posts_controller.rb:
def create
#post = current_user.posts.build(params[:post])
if params[:commit] == "Publish"
#post.status = "Published"
elsif params[:commit] == "Save Draft"
#post.status = "Draft"
end
respond_to do |format|
format.html do
if #post.save && #post.status == "Published"
flash[:success] = "Post published"
redirect_to #post
elsif #post.save && #post.status == "Draft"
flash[:success] = "Post saved as draft"
render 'edit'
else
render 'new'
end
end
format.js do
#post.save
end
end
end
posts/create.js.erb:
<% if #post.errors.any? %>
alert('There are errors.');
<%= render :partial=>'js_errors', :locals=> { :target=> #post } %>
<% else %>
$('.busy').html('Saved.');
<% end %>
js_errors.js.erb:
<% target.errors.full_messages.each do |error| %>
$('.busy').append('<p><%= escape_javascript( error ) %></p>');
<% end %>
posts/new.html.erb:
<%= form_for(#post, remote: true, :html => { :multipart => true }) do |f| %>
<%= render 'fields', f: f %>
<div class="form-actions">
<%= f.submit "Publish", class: "publish btn btn-primary pull-left" %>
<%= f.submit "Save Draft", class: "save-draft btn btn-default pull-left" %>
<div class="busy pull-left">
</div>
</div>
<% end %>
But for some reason nothing displays (.busy always remain empty).
In the console I can see that js_errors.js.erb is being displayed:
Started POST "/posts" for 127.0.0.1 at 2013-01-04 18:02:18 +0800
Processing by PostsController#create as JS Parameters: {"utf8"=>"✓",
"authenticity_token"=>"Qfn6HsPPDxyB1t4bM/OQKPbJ/aoAMkp74y0Z6xkoXCY=",
"post"=>{"title"=>"", "content"=>"", "tag_list"=>""},
"_wysihtml5_mode"=>"1", "commit"=>"Save Draft"} User Load (0.7ms)
SELECT "users".* FROM "users" WHERE "users"."remember_token" =
'ljl0ZsuoiHg0Jilz8bgy-g' LIMIT 1 (0.2ms) begin transaction
(0.2ms) rollback transaction Rendered posts/_js_errors.js.erb
(3.8ms) Rendered posts/create.js.erb (7.5ms) Completed 200 OK in
25ms (Views: 11.2ms | ActiveRecord: 1.0ms | Solr: 0.0ms)
What could be the problem?
(I do see the validation messages if I remove remote:true from the form).
EDIT:
I noticed alert('There are errors.'); is not being triggered. Strange.
It looks like a naming problem. You're asking to render the partial js_errors, which would be called _js_errors.js.erb; but you say your file is actually called js_errors.js.erb (no leading underscore).
Try adding the underscore and see if that helps matters.
I have been facing a similar problem a few days ago. I used remote => true option in my form to use Ajax in my Rails 3 application. After that, I have been looking for solution for validating my form fields. After trying a good number of jQuery / Javascript approaches (none of them worked for me though) I came to know about a superb gem called client_side_validations. It is very easy to install by following the instructions on github link (https://github.com/bcardarella/client_side_validations). It works like charm for client side validation of form fields, an awesome gem indeed. Hope this helps with people who are tired of looking for a simple solution for client side validation of model fields after using Ajax in Rails 3 application.