Not able to save form data into database in rails - ruby-on-rails

I have created a scaffold name project and created another scaffold named
stage. There is one to many associate between project and stage. like each project will have multiple stages. I am able to render stage form but i am not able to save data into stage table of the database.
this error i get on saving stage form
stage form.html.erb
<%= form_with(model: stage, url: [#project, stage], local: true) do |form| %>
<% if #stage.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(stage.errors.count, "error") %> prohibited this stage from being saved:</h2>
<ul>
<% stage.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="row select-date-wrapper">
<div class="field columns large-6">
<%= form.label :stage %>
<%= form.text_field :stage %>
</div>
<div class="field columns large-3">
<%= form.label :planned_start_date %>
<%= form.date_select :planned_start_date, class: 'select-date' %>
</div>
<div class="actions">
<%= form.submit 'Create', :class=>"button primary small" %>
</div>
<% end %>
stage_controller.rb
def index
#stages = Stage.all
end
def new
#stage = Stage.new
#project = Project.find(params[:project_id])
end
def create
#project = Project.find(params[:project_id])
#stage = #project.stages.build(stage_params)
respond_to do |format|
if #stage.save
format.html { redirect_to #stage, notice: 'Stage was successfully created.' }
format.json { render :show, status: :created, location: #stage }
else
format.html { render :new }
format.json { render json: #stage.errors, status: :unprocessable_entity }
end
end
end
model project.rb
has_many :stages
model stage.rb
#belongs_to :project
has_many :tasks
routes.rb
resources :projects do
resources :stages
end

Have you tried this?
if #stage.save
format.html { redirect_to project_stage_path(#project, #stage), notice: 'Stage was successfully created.' }
format.json { render :show, status: :created, location: #stage }
else
format.html { render :new }
format.json { render json: #stage.errors, status: :unprocessable_entity }
end

please change url: [#project, stage] to url: stages_path
always try to make controller name plural. stages_controller

Related

Error in rails 5 form on Create

I am new in rails and I'm trying to make a form to associate roles with users, I have two collection_select in the form but when I want to create or update I get this error:
my controller code is :
class UserRolesController < ApplicationController
before_action :set_user_role, only: [:show, :edit, :update, :destroy]
##roles =RolesController.new
##users =UsersController.new
# GET /user_roles
# GET /user_roles.json
def index
#user_roles = UserRole.all
end
# GET /user_roles/1
# GET /user_roles/1.json
def show
end
# GET /user_roles/new
def new
#user_role = UserRole.new
#users =##users.get_all_users
#roles =##roles.get_all_roles
end
# GET /user_roles/1/edit
def edit
#users =##users.get_all_users
#roles =##roles.get_all_roles
#user_roles =UserRole.find(params[:id])
#selected_role=#user_roles.role_id
#selected_user=#user_roles.user_id
end
# POST /user_roles
# POST /user_roles.json
def create
#user_role = UserRole.new(user_role_params)
respond_to do |format|
if #user_role.save
format.html { redirect_to #user_role, notice: 'User role was successfully created.' }
format.json { render :show, status: :created, location: #user_role }
else
format.html { render :new }
format.json { render json: #user_role.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /user_roles/1
# PATCH/PUT /user_roles/1.json
def update
respond_to do |format|
if #user_role.update(user_role_params)
format.html { redirect_to #user_role, notice: 'User role was successfully updated.' }
format.json { render :show, status: :ok, location: #user_role }
else
format.html { render :edit }
format.json { render json: #user_role.errors, status: :unprocessable_entity }
end
end
end
# DELETE /user_roles/1
# DELETE /user_roles/1.json
def destroy
#user_role.destroy
respond_to do |format|
format.html { redirect_to user_roles_url, notice: 'User role was successfully destroyed.' }
format.json { head :no_content }
end
end
def get_user_role_by_userid(user_id)
return UserRole.where(user_id:user_id).first
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user_role
#user_role = UserRole.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_role_params
params.require(:user_role).permit(:role_id,:user_id)
end
end
My form code is :
<%= form_for(user_role) do |f| %>
<% if user_role.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(user_role.errors.count, "error") %> prohibited this user_role from being saved:</h2>
<ul>
<% user_role.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :user %>
<%= collection_select(:user_id, :user_id,#users, :id, :name,{:selected => #selected_user}) %>
</div>
<div class="field">
<%= f.label :rol %>
<%= collection_select(:role_id, :role_id,#roles, :id, :role {:selected => #selected_role}) %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
What i am doing wrong? , how i have to set the user_role_params in this case?
I am using ruby 2.3.1 and Rails : 5.0.1
Thanks for your suggestions.
You need to put an f before collection set like this:
<%= form_for(user_role) do |f| %>
<% if user_role.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(user_role.errors.count, "error") %> prohibited this user_role from being saved:</h2>
<ul>
<% user_role.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :user %>
<%= f.collection_select(:user_id, #users, :id, :name,{:selected => #selected_user}) %>
</div>
<div class="field">
<%= f.label :rol %>
<%= f.collection_select(:role_id, #roles, :id, :role {:selected => #selected_role}) %>
</div>
<div class="actions">
<%= f.submit %>
</div>
otherwise the params are being sent like user_id instead of user_role[user_id]

How to make ajax call and show error messages

Two of the action of My registration controller is new and create.
def new
#regist = Regist.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #regist }
end
end
def create
#regist = Regist.new(regist_params)
respond_to do |format|
if #regist.save
format.html { redirect_to #regist, notice: 'Regist was successfully created.' }
format.json { render json: #regist, status: :created, location: #regist }
else
format.html { render action: "new" }
format.json { render json: #regist.errors, status: :unprocessable_entity }
end
end
end
And the new form contain following code.
<%= form_for(#regist) do |f| %>
<% if #regist.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#regist.errors.count, "error") %> prohibited this regist from being saved:</h2>
<ul>
<% #regist.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.collection_select :student_id, Student.all, :id, :name %><br />
</div>
<div class="field">
<%= f.collection_select :semester_id, Semester.all, :id, :name %><br />
</div>
<div class="field">
<% for subject in Subject.find(:all) %>
<%= check_box_tag "regist[subject_ids][]", subject.id %>
<%= subject.name %><br>
<% end %>
</div>
<div class="field">
<%= f.label :date_of_birth %><br />
<%= f.text_field :date_of_birth %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Now, when someone click on submit button I want to make ajax call using remote true if there are validation errors and show the errors without reloading the page. And if there are no validation errors I want the user to be redirected to show page. How can I do this?
First of all you should add a remote: true to your existing form to allow remote action.
TODO this just add on the first line of your form the remote: true,
<%= form_for(#regist, remote: true) do |f| %>
the rest leave it as it is. Then you need to make your controller to respond to remote calls, therefore you need to alter the responds_to block of create action:
respond_to do |format|
if #regist.save
format.html { redirect_to #regist, notice: 'Regist was successfully created.' }
format.json { render json: #regist, status: :created, location: #regist }
format.js { render js: "window.location.href='"+regists_path+"'"}
else
format.html { render action: "new" }
format.json { render json: #regist.errors, status: :unprocessable_entity }
format.js
end
end
The last step you have to do is to add a file to your app/views/regists/ directory
where you should add a create.js.erb file:
<% if #regist.errors.any? %>
$('#new_regist').effect('highlight', { color: '#FF0000'}, 1000); // for highlighting
// or add here whatever jquery response you want to have to your views.
<% end %>
You will get your validation errors displayed like before above the form.
You have to add the redirect to your controller to the desirable action of your choice. I have added for you a window.location.href as a response to the regists_path.

Rails create form for model with many to many relation

I have two models, Recipe and Tag, with a has_and_belongs_to_many relation. For this relation I have a simple join table, RecipesTags.
Recipe:
has_and_belongs_to_many :tags
Tag:
has_and_belongs_to_many :recipes
Now upon creating a new recipe, the user gets to fill in which category the recipe belongs to in forms of checkboxes, like "Meat", "Fish", and so on. These categories are in fact just tags in the database.
Problem: the recipes doesn't get any tags saved to it.
Recipe new and create controller methods:
def new
#recipe = Recipe.new
#ingredients = Ingredient.all
#tags = Tag.all
respond_to do |format|
format.html # new.html.erb
format.json { render json: #recipe }
end
end
# POST /recipes
# POST /recipes.json
def create
#recipe = Recipe.new(params[:recipe])
if (params[:tags])
#recipe.tags << params[:tags]
end
respond_to do |format|
if #recipe.save
format.html { redirect_to #recipe, notice: 'Recipe was successfully created.' }
format.json { render json: #recipe, status: :created, location: #recipe }
else
format.html { render action: "new" }
format.json { render json: #recipe.errors, status: :unprocessable_entity }
end
end
end
The view:
<%= form_for(#recipe, :html => {:multipart => true}) do |f| %>
<% if #recipe.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#recipe.errors.count, "error") %> prohibited this recipe from being saved:</h2>
# [ fields that get's saved for the recipe and works fine ]
<% #tags.each do |t| %>
<%= f.label t.name %>
<%= f.check_box :tags, t.name %>
<br />
<% end %>
<%= f.submit 'Submit recipe', :class => 'btn btn-primary' %>
<% end %>
At the moment, I get an error message saying:
undefined method `merge' for "Meat":String
"Meat" is the tag name.
So, what am I doing wrong here?
I think the issue is this line #recipe.tags << params[:tags].
The association method you're calling with << takes an object (in this case expecting a tag object), but in this case it seems you might be passing it a string.
For more info this link may be helpful http://guides.rubyonrails.org/association_basics.html#has_and_belongs_to_many-association-reference, in particular where it refers to collection<<(object, …).
In your controller you'll want to do something like #recipe.tags << tag where tag is a specific tag object.
So, try this:
In your controller
params[:tags].each do |k,v|
#recipe.tags << Tag.find(k)
end
In your view
<% #tags.each do |t| %>
<%= f.label t.name %>
<%= f.check_box "tags[#{t.id}]" %>
<br />
<% end %>
Try this:
def create
#recipe = Recipe.new(params[:recipe])
params[:tags].each do |tag|
#recipe.tags << Tag.find_by_name(tag)
end
respond_to do |format|
if #recipe.save
format.html { redirect_to #recipe, notice: 'Recipe was successfully created.' }
format.json { render json: #recipe, status: :created, location: #recipe }
else
format.html { render action: "new" }
format.json { render json: #recipe.errors, status: :unprocessable_entity }
end
end
end
In view:
<% #tags.each do |t| %>
<%= label_tag t.name %>
<%= check_box_tag "tags[#{t.name}]", t.name %>
<br />
<% end %>

view incorrectly reloads after uniqueness validation error

After you try to submit a new guideline and you see an error message on the form (due to the guidelines correctly failing validation)...the list of #specialties does not reload correctly (ie. it just says yes/no rather than the proper list you could see before you submitted with an error). I can't work out which part is wrong here...
VIEWS _form.html.erb
<%= simple_form_for(#guideline, html: {class: "form-horizontal"}) do |f| %>
<% if #guideline.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#guideline.errors.count, "error") %> prohibited this guideline from being saved:</h2>
<ul>
<% #guideline.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.input :title, label: 'Title (e.g. Asthma for under 12 months)' %>
<%= f.input :specialty, as: :select, collection: #specialties %>
<%= f.input :hospital %>
<%= f.input :content, as: :string, label: 'Link' %>
<div class="form-actions">
<%= f.button :submit, :class => "btn btn-info btn-large" %>
</div>
<% end %>
guidelines_controller.rb
def new
#guideline = Guideline.new
#specialties = Guideline.order(:specialty).uniq.pluck(:specialty)
respond_to do |format|
format.html # new.html.erb
format.json { render json: #guideline }
end
end
def create
#guideline = current_user.guidelines.new(params[:guideline])
respond_to do |format|
if #guideline.save
format.html { redirect_to #guideline, notice: 'Guideline was successfully created.' }
format.json { render json: #guideline, status: :created, location: #guideline }
else
#specialties = Guideline.order(:specialty).uniq.pluck(:specialty)
format.html { render action: "new" }
format.json { render json: #guideline.errors, status: :unprocessable_entity }
end
end
end
this is a common error. in your create action you should declare #specialties if the validation fails since that is needed in the new template.
def create
#guideline = Guideline.new params[:guideline]
if #guideline.save
else
# you need to declare #specialties here since it is needed in the new template
# which you want to render
#specialties = Specialty.all
render :new
end
end

Rails 3.2 - Nested Resource Passing ID

Okay so my associations are:
Outlet -> has_many :monitorings
Monitoring -> belongs_to :outlet
My Routes:
resources :outlets do
resources :monitorings
end
View:
<%= link_to new_outlet_monitoring_path(#outlet) %>
When I click the link, the logs show that the outlet_id is passed as a parameter to the new page correctly.
But when saving the monitoring record, the outlet_id becomes nil.
Any help?
UPDATE:
# views/monitorings/_form.html.erb
<%= form_for(#monitoring) do |f| %>
<h2>Type of Monitoring</h2>
<fieldset data-role="controlgroup" >
<div class="radio-group">
<%= f.radio_button :mtype, "Full" %><%= f.label :mtype, "Full", value: "Full" %>
<%= f.radio_button :mtype, "Partial" %><%= f.label :mtype, "Partial", value: "Partial" %>
<%= f.radio_button :mtype, "None" %><%= f.label :mtype, "None", value: "None" %>
</div>
</fieldset>
<hr>
<%= f.submit "Next Step" %>
<% end %>
And the controller:
# controllers/monitoring_controller.rb
def new
#monitoring = Monitoring.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #monitoring }
end
end
def create
#monitoring = Monitoring.new(params[:monitoring])
respond_to do |format|
if #monitoring.save
format.html { redirect_to #monitoring, notice: 'Monitoring was successfully created.' }
format.json { render json: #monitoring, status: :created, location: #monitoring }
else
format.html { render action: "new" }
format.json { render json: #monitoring.errors, status: :unprocessable_entity }
end
end
end
This is most likely an issue with the way you are creating the new monitoring record. Can we see your form and your create controller action?

Resources