I am new in ror and when I submit my form:
<%= form_for :project, url: projects_path, html: {id:'form'} do |f| %>
<%= f.text_field :text, placeholder: 'Новая задача' %>
<%= link_to 'Отмена', '', id:'cancel_link' %>
<%= link_to 'Отправить', projects_path, id:'submit_link' %>
<% end %>
Have error:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"OR2HWCi3zVz9gB5VAmnzbEuzIwFGE58JlLrWQdNcws6FVTzqh5Cu0zvUJTUEv2O/sCvU9HuadJYr3mfA40ehGA==", "project"=>{"text"=>"NEW ITEM"}} Unpermitted parameter: :text
Have two models:
class Project < ApplicationRecord
has_many :todos
validates :title, presence: true
accepts_nested_attributes_for :todos
end
class Todo < ApplicationRecord
belongs_to :project, required: false
end
The Todo model has a text attribute in which our todo should be located
Controller
class ProjectsController < ApplicationController
def index
#projects = Project.all
end
def create
#project = Project.new(project_params)
if #project.save
redirect_to root_path
end
end
def update
end
private
def project_params
params.require(:project).permit(:title, todos_attributes: [:id, :text])
end
end
Project db
class CreateProjects < ActiveRecord::Migration[5.2]
def change
create_table :projects do |t|
t.string :title
t.string :todos
t.timestamps
end
Todo db
class CreateTodos < ActiveRecord::Migration[5.2]
def change
create_table :todos do |t|
t.text :text
t.boolean :isCompleted
t.integer :project_id
t.timestamps
end
I'm requesting the todo attributes using accepts_nested_attributes_for: todos, the controller is also registered on the guides, in project_params I request todos_attributes. But when sending a form to the database, the value is text. He does not save in db. Can u help please
In order to save text field in Todo model, you have to create nested form. Use nested_form gem for this purpose.
A vague example to show how it works:
<%= nested_form_for :project, url: projects_path, html: { id: 'form' } do |f| %>
<%= f.text_field :title, placeholder: 'Новая задача' %>
<%= f.fields_for :todos do |todo_form| %>
<%= todo_form.text_field :text %>
<%= todo_form.link_to_remove "Remove this todo" %>
<% end %>
<p><%= f.link_to_add "Add a todo", :todos %></p>
<%= link_to 'Отмена', '', id:'cancel_link' %>
<%= link_to 'Отправить', projects_path, id:'submit_link' %>
<% end %>
In controller, to have the functionality of removing a todo in case of editing a project:
def project_params
params.require(:project).permit(:title, todos_attributes: [:id, :text, _destroy])
end
In the migration CreateProjects < ActiveRecord::Migration[5.2], I do not think that you require todos as a string.
The form which you created is wrong, you need to create a nestead_form
It is giving you and Unpermitted parameter error because the text is not a field of project model you can check this on your migration file. You need to change it to title because the title is the field of project model.
And for to create a nested form you need to do some changes in your form
<%= form_for :project, url: projects_path, html: {id:'form'} do |f| %>
<%= f.text_field :title, placeholder: 'Новая задача' %>
<%= f.fields_for :todos do |todo| %>
<%= f.text_field :text %>
<% end %>
<%= link_to 'Отмена', '', id:'cancel_link' %>
<%= link_to 'Отправить', projects_path, id:'submit_link' %>
<% end %>
Related
I tried to create edit and update action for my assosiated model named as Entity.
But When edit pages pop up no saved data shown. Means it is showing all field as empty and when I put values in it, creates a another object.
And also validation messages are not showing
Entities Controller
class EntitiesController < ApplicationController
def edit
#schema = Schema.find(params[:schema_id])
#entity = #schema.entities.find(params[:id])
end
def update
#schema = Schema.find(params[:schema_id])
#entity = #schema.entities.find(params[:id])
if #entity.update(entity_params)
redirect_to schema_entities_path(#schema)
else
render 'edit'
end
end
private
def entity_params
params.require(:entity).permit(:clientId, :name, :description, :mnemonic)
end
end
edit form for it:
<%= form_for([#schema, #schema.entities.build], data: { turbo: false }) do |f| %>
<%= f.text_field :clientId, placeholder:"ClientId" %>
<%= f.text_area :name, placeholder: "Name" %>
<%= f.text_area :description, placeholder: "Description" %>
<%= f.text_area :mnemonic, placeholder: "Mnemonic" %>
<%= f.submit 'Submit' %>
<% if #entity.errors.any? %>
<div id="error_explanation">
<% #entity.errors.full_messages.each do |msg| %>
<p class="error_msg"><%= msg %></p>
<% end %>
</div>
<% end %>
<% end %>
Its model:
class Entity < ApplicationRecord
belongs_to :schema
has_many :fields, dependent: :destroy
has_many :joins, through: :fields
validates :name, presence: true, uniqueness: true
def self.search(search)
where("name LIKE ?", "%#{search}%")
end
end
This is how I am passing values from index page:
<%= link_to 'Edit', edit_schema_entity_path(schema_id: #schema.id, id: data.id) if data.id %>
I have 2 Models: Unit and Emp
Also I have 2 controllers: Units and Emps
class CreateEmps < ActiveRecord::Migration[6.0]
def change
create_table :emps do |t|
t.string :name
t.references :unit
t.timestamps
end
end
end
class CreateUnits < ActiveRecord::Migration[6.0]
def change
create_table :units do |t|
t.string :name
t.timestamps
end
end
end
Looks simple.... but I guess too simple. I haven't found example how to do the following:
I need to have form for Emp creation.
So my question is .... how should it look like?
I want to have ComboBox with list of all objects in Units.
<%= form_with model: #emp do |f| %>
<p><%= f.label :name %>
<%= f.text_field :name %> </p>
<!-- What should go here? to ComboBox (option->select) -->
<%= f.submit "Create" %>
<% end %>
I am also confused how should it look like regargding emp_params for permiting.
EDIT:
class EmpsController < ApplicationController
def new
#emp = Emp.new
#unit_options = Unit.all.collect{|unit| [unit.name, unit.id] }
end
def create
#emp = Emp.new(emp_params)
#emp.save
redirect_to :action => :list
end
def destroy
#emp = Emp.find([:id])
#emp.destroy
redirect_to :action => :list
end
def list
#emps = Emp.all
end
def emp_params
params.require(:emp).permit(:name, :unit_id)
end
end
You want to use a select tag.
In your controller:
#unit_options = Unit.all.collect{|unit| [unit.name, unit.id] }
This creates a list of names and IDs, the order of each is name then value for the select option. You can of course scope or filter the results as needed.
In your view:
<%= form_with model: #emp do |f| %>
<div>
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div>
<%= f.label :unit_id, 'Unit' %>
<%= f.select :unit_id, #unit_options, {include_blank: true} %>
</div>
<%= f.submit "Create" %>
<% end %>
When used to edit the model, rails will select the option for the current value.
I have been following both the old and revised railscasts & this for something that i have to make along the same lines
I followed it upto some point but neither are the questions being displayed on the form nor are the answers getting added . Following is my model code
answers.rb
class Answer < ActiveRecord::Base
attr_accessor :content, :question_id
belongs_to :question
end
surveys.rb
class Survey < ApplicationRecord
attr_accessor :name, :questions_attributes
has_many :questions
accepts_nested_attributes_for :questions, allow_destroy: true
end
questions.rb
class Question < ApplicationRecord
attr_accessor :content, :survey_id, :answers_attributes
belongs_to :survey
has_many :answers
accepts_nested_attributes_for :answers, allow_destroy: true
end
Surveys Controller
class SurveysController < ApplicationController
before_action :set_survey, only: [:show, :edit, :update, :destroy]
# GET /surveys
# GET /surveys.json
def index
#surveys = Survey.all
end
# GET /surveys/1
# GET /surveys/1.json
def show
end
# GET /surveys/new
def new
#survey = Survey.new
3.times do
question = #survey.questions.build
4.times { question.answers.build }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_survey
#survey = Survey.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def survey_params
params.require(:survey).permit(:name, :question_id)
end
end
Views
_form.html.erb
<%= f.fields_for :questions do |builder| %>
<%= render 'question_fields', f: builder %>
<% end %>
<%= link_to_add_fields "Add Question", f, :questions %>
_question_fields.html.erb
<fieldset>
<%= f.label :content, "Question" %><br />
<%= f.text_area :content %><br />
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove Question" %>
<%= f.fields_for :answers do |builder| %>
<%= render 'answer_fields', f: builder %>
<% end %>
<%= link_to_add_fields "Add Answer", f, :answers %>
</fieldset>
_answers_fields.html.erb
<p>
<%= f.label :content, "Answer" %>
<%= f.text_field :content %>
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove" %>
</p>
show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #survey.name %>
</p>
<ol>
<% for question in #survey.questions %>
<li><%= h question.content %></li>
<% end %>
</ol>
<p>
<%= link_to "Edit", edit_survey_path(#survey) %> |
<%= link_to "Destroy", #survey, :confirm => 'Are you sure?', :method => :delete %> |
<%= link_to "View All", surveys_path %>
</p>
Migrations
class CreateSurveys < ActiveRecord::Migration[5.0]
def change
create_table :surveys do |t|
t.string :name
t.timestamps
end
end
end
class CreateQuestions < ActiveRecord::Migration[5.0]
def change
create_table :questions do |t|
t.string :survey_id
t.string :integer
t.text :content
t.timestamps
end
end
end
Is there anything else i am missing out that needs to be done in rails 5 , i have been hours at this and it still confuses me why does it show me this error - Table 'app.answers' doesn't exist when i am calling answers from nested form . Any help in this regard would be very much appreciated .
The main issue here is it looks like you forgot an 'answer' migration to create the tables, create that and run it and should fix things up.
Additionally, those attr_accessor calls are going to be messing things up. They were required in older versions of Rails, but aren't anymore and now just serve throw things off. Example
With attr_accessor code
post = Post.new(title: "Something")
#=> #<Post id: nil, title: nil, created_at: nil, updated_at: nil>
post.title = "Something"
#=> "Something"
puts post
#=> #<Post id: nil, title: nil, created_at: nil, updated_at: nil>
Without
post = Post.new(title: "Something")
#=> #<Post id: nil, title: "Something", created_at: nil, updated_at: nil>
post.title = "Something Else"
#=> "Something Else"
puts post
#=> #<Post id: nil, title: "Something Else", created_at: nil, updated_at: nil>
As you can see, the first block, where my Post model had the attr_accessor for the title attribute, nothing was working as expected; I couldn't update the title. Once I removed it, things started to work as they should.
Based on the chat discussion, your _form.html.erb is missing form_for tag, and should looks something like
<%= form_for #survey do |f| %>
<%= f.label :name %><br />
<%= f.text_field :name %>
<!-- your current code here -->
<% end %>
you've got _answers_field.html.erb and in _question_fields.html.erb are calling
<%= render 'answer_fields', f: builder %>
Notice, the plural/singular mismatch.
and lastly, in your controller, you aren't permitting the nested attribute params which should end up looking like (unless I'm mistaken)
def survey_params
params.require(:survey).permit(:name, :question_attributes: [:id, :content, :_destroy, answer_attributes: [:id, :content, :_destroy])
end
Last couple of issues from chat were that the associations needed inverse_of because belongs_to is required by default in rails 5. And the last minor thing is that Answer is currently inheriting ActiveRecord::Base and the other models ApplicationRecord
I saw a similar answered question here which got me this far. But now I am facing an error in Form. The solution I am looking for is basically saving to two tables in Ruby Rails where saving the Property with address in first table also saves 2 images in Pictures' second table.
Migration1:
class CreateProperties < ActiveRecord::Migration[5.0]
def change
create_table :properties do |t|
t.string :address
t.timestamps
end
end
end
Migration2:
class CreatePictures < ActiveRecord::Migration[5.0]
def change
create_table :pictures do |t|
t.string :image1
t.string :image2
t.timestamps
end
end
end
Property Model:
class Property < ApplicationRecord
has_many :pictures
accepts_nested_attributes_for :pictures
end
Picture Model:
class Picture < ApplicationRecord
belongs_to :property
end
PropertiesController:
class PropertiesController < ApplicationController
before_action :set_property
def new
#property = Property.new
end
def create
#property = properties.build(property_params)
if #property.save
flash[:success] = "Property was successfully created"
redirect_to property_path(#property)
else
render 'new'
end
end
private
def property_params
params.require(:property).permit(:address, picture_attributes: [:image1, :image2])
end
end
The FORM which I don't know is done as below:
<%= form_for(#property) do |f| %>
<%= f.label :address %>
<%= f.text_field :address %>
<%= f.label :image1 %>
<%= f.text_field :image1 %>
<%= f.label :image2 %>
<%= f.text_field :image2 %>
<%= f.submit %>
<% end %>
Error Picture:
Error on new.html.erb
You should use the fields_for method to have a form for pictures inside the property form:
# inside the property form_for
<%= f.fields_for #property.pictures.build do |p| %>
<%= p.file_field :image1 %>
<%= p.file_field :image2 %>
<% end %>
I keep get this error when I want to render my form
The error is pointing the <%= form_for(#hreport) do |f| %>, I'm not sure where when wrong or i missed something, anyone help is appreciate!
<div class="col-md-6 col-md-offset-3">
<%= form_for(#hreports) do |f| %>
<%= f.label :"Student ID" %>
<%= f.text_field :studentid, class: 'form-control' %>
This is my health_report_controller.rb
class HealthReportController < ApplicationController
def index
#hreports = Healthreport.where(:user_id => current_user.id)
end
def new
#hreports = Healthreport.new
end
def create
#hreports = current_user.healthreports.build(hreport_params)
if #hreports.save
flash[:success] = "Report Submitted!"
else
end
end
def show
#hreports = Healthreport.find(params[:id])
end
private
def set_hreport
#hreport = Healthreport.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def hreport_params
params.require(:Healthreport).permit(:date, :studentid, :department, :issue)
end
end
This is my view
<% provide(:title, 'New Report') %>
<h1>Health and Safety Report</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#hreports) do |f| %>
<%= f.label :"Student ID" %>
<%= f.text_field :studentid, class: 'form-control' %>
<%= f.label :"Department of applicant" %>
<%= f.text_field :department, class: 'form-control' %>
<%= f.label :"Description of Issues" %>
<%= f.text_area :issue, placeholder: "Write your report here...", class: 'form-control' %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
This is my healthreport.rb inside model folder
class Healthreport < ApplicationRecord
belongs_to :user
end
This is my healthreport.rb inside db folder
class CreateHealthreports < ActiveRecord::Migration[5.0]
def change
create_table :healthreports do |t|
t.datetime :date
t.string :studentid
t.string :department
t.string :issue
t.timestamps
end
end
end
It's migration db file
class AddUserToHealthreport < ActiveRecord::Migration[5.0]
def change
add_reference :healthreports, :user, foreign_key: true
end
end
In your controller, you do this:
def new
#hreports = Healthreport.new
end
But in the view, you are expecting this
<%= form_for(#hreport) do |f| %>
You are passing #hreports but trying to use #hreport. Change the controller to be
def new
#hreport = Healthreport.new
end
(the index action should use the plural, the other actions should use the singular)
Two Rails convention/style things you should be aware of:
A singular variable name (such as #hreport) refers to a single object; a plural of that name (#hreports) refers to an array or an ActiveRecord relationship.
Model and Controller should use the same naming style: if the controller is named health_report_controller.rb and defines a HealthReportController, then the model file should be named health_report.rb and should define a HealthReport class.