Edit form rendered blank - ruby-on-rails

My model/id/edit form is rendered blank, without rendering the values that are already in the database. I don't see this is the regular behaviour in a brand new rails app.
Any insights what's blocking those values to be rendered in the form?
Rails 6.1.4
ruby 2.7.3p183
_form.html.erb
<%= form_with(model: task) do |form| %>
<%= render "shared/error_messages", resource: form.object %>
<div class="form-group">
<%= form.label :title %>
<%= form.text_field :title, class: "form-control", prepopulated: "true", :value => params[:title] %>
</div>
<div class="form-group">
<%= form.label :description %>
<%= form.rich_text_area :description, data: { controller: "mentions", mentions_target: "field" }, class: "form-control", :value => params[:description] %>
</div>
<div class="form-group">
<%= form.label :credits %>
<%= form.number_field :credits, class: "form-control", :value => params[:credits] %>
</div>
<div class="form-group">
<%= form.label :category %>
<%= form.select :category, [ 'Development', 'Design' ], class: "form-control", :value => params[:category] %>
</div>
<% if current_user.admin === true %>
<%= form.collection_check_boxes(:user_ids, User.where(id: 1).all, :id, :name) do |u| %>
<%= u.label(class: "check_box") { u.check_box(checked: true, class: "add_margin") + u.text } %>
<% end %>
<% end %>
<div class="flex justify-between form-group">
<%= form.button class: "btn btn-primary" %>
<% if form.object.persisted? %>
<%= link_to t("delete"), form.object, class: "btn btn-danger outline", method: :delete, data: { confirm: t("are_you_sure") } %>
<% end %>
</div>
<% end %>
Controller
class TasksController < ApplicationController
before_action :set_task, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
before_action :load_entities, only: :show
# GET /tasks/1/edit
def edit
end
# PATCH/PUT /tasks/1 or /tasks/1.json
def update
respond_to do |format|
if #task.update(task_params)
format.html { redirect_to #task, notice: "Task was successfully updated." }
format.json { render :show, status: :ok, location: #task }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_task
#task = Task.find(params[:id])
puts #task
puts #task.id
end
# Only allow a list of trusted parameters through.
def task_params
params.require(:task).permit(:title, :description, :credits, :deliverydate, :submitteddate, :createdby, :default, :status, :category, :assignedto, user_ids: [])
end
end
Edit:
Adding trace for set_task , example when opening the Edit form for Task ID 7
10:30:24 web.1 | ↳ app/controllers/tasks_controller.rb:91:in `set_task'
10:30:24 web.1 | #<Task:0x000000010d75ddf8>
10:30:24 web.1 | 7
10:30:24 web.1 | Rendering layout layouts/application.html.erb

Related

Uploading and getting Active Storage Blob before saving full record

Is it possible to set up a Rails form in a way that a user can upload images, and then be shown the direct link for their image before saving the rest of the form?
Use Case:
The use case is trying to be able to allow users to upload images, and then before saving the rest of the post, get links for those images and use the links in their markdown form in the same form.
I'm not familiar with Turbo, but maybe that's the way to go?
What I Have:
guide.rb
class Guide < ApplicationRecord
extend FriendlyId
friendly_id :title, use: :slugged
has_many_attached :images
acts_as_taggable_on :season, :tag
validates_presence_of :season_list, message: 'at least one season tag must be added'
validates_inclusion_of :season_list, in: %w[Spring Summer Fall Winter], message: '%<value>s is not a valid season'
end
guides_controller.rb
class GuidesController < ApplicationController
skip_before_action :verify_authenticity_token, only: %i[update_tags]
before_action :set_guide, only: %i[show edit update destroy]
rescue_from ActiveRecord::RecordNotFound, with: :guide_not_found
...
# GET /guides/new
def new
#guide = Guide.new
end
# GET /guides/1/edit
def edit; end
# POST /guides or /guides.json
def create
#guide = Guide.new(guide_params)
respond_to do |format|
if #guide.save
format.html { redirect_to guide_url(#guide), notice: 'Guide was successfully created.' }
format.json { render :show, status: :created, location: #guide }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #guide.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /guides/1 or /guides/1.json
def update
respond_to do |format|
if #guide.update(guide_params)
format.html { redirect_to guide_url(#guide), notice: 'Guide was successfully updated.' }
format.json { render :show, status: :ok, location: #guide }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #guide.errors, status: :unprocessable_entity }
end
end
end
...
private
# Only allow a list of trusted parameters through.
def guide_params
params.require(:guide).permit(:title, :body, :tag_list, :tags, season_list: [], images: [])
end
end
_form.html.erb
<%= form_with(model: guide, class: "contents", multipart: true) do |form| %>
<% if guide.errors.any? %>
<div id="error_explanation" class="bg-red-50 text-red-500 px-3 py-2 font-medium rounded-lg mt-3">
<h2><%= pluralize(guide.errors.count, "error") %> prohibited this guide from being saved:</h2>
<ul>
<% guide.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="my-5">
<%= form.label :title %>
<%= form.text_field :title, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-full" %>
</div>
<div class="my-5">
<%= form.label :season %>
<% %w(Spring Summer Fall Winter).each do |season| %>
<%= form.check_box :season_list, { multiple: true }, season, nil %>
<%= label_tag season %>
<% end %>
</div>
<div class="my-10" data-controller="tagify">
<%= form.hidden_field :tag_list, value: #guide.tag_list.to_s, data: {"tagify-target": "hiddenField"} %>
<%= form.label :tags %>
<div >
<div data-tagify-target="input"></div>
</div>
</div>
<div class="py-10">
<%= form.label :image %>
<%= form.file_field :image, multiple: true, direct_upload: true, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-full" %>
</div>
<div class="my-5">
<%= form.label :body %>
<%= form.text_area :body, rows: 4, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-full" %>
</div>
<div class="inline">
<%= form.submit class: "rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer" %>
</div>
<% end %>
Any help or direction to research is appreciated.

Simple_Fields_For not saving data of child record

I am currently trying to fix the relationship between delivery, delivery_orders and orders model. I've been trying all day to save a nested form that stores the orders inside of the delivery_orders table. Essentially, I want to be able to create deliveries, and then add orders to the deliveries through the delivery_order model. Normal users create orders, but Managers handle deliveries for those orders. So far, I've been unable to save the nested simple_form_for section for delivery_order model. It keep returning nil, even though the relationship is setup to support the transaction. One side note, I am unable to read the attributes of the orders through the delivery model. The code that I wrote is below. Structure User -> Order -> Manager Delivery[Delivery_order] -> Truck[Delivery]
delivery.rb
class Delivery < ApplicationRecord
belongs_to :warehouse, optional: true
belongs_to :truck, optional: true
has_one :delivery_order
has_one :order_tracker
has_many :breads
#after_create :decrement_bread_stock
accepts_nested_attributes_for :delivery_order
end
deliveryorder.rb
class DeliveryOrder < ApplicationRecord
has_many :orders, inverse_of: :delivery_order
belongs_to :delivery, optional: true
end
order.rb
class Order < ApplicationRecord
belongs_to :client, :dependent => :destroy, optional: true
belongs_to :delivery_order, optional: true
has_one :bread
has_one :order_tracker, :dependent => :destroy
after_create :build_order_tracker
geocoded_by :address, :latitude => :lat, :longitude => :lon
after_validation :geocode, if: ->(obj) {obj.client_address.present? && obj.client_address_changed?}
def address
[client_address, client_state].compact.join(', ')
end
end
deliveries_controller.rb
class DeliveriesController < ApplicationController
before_action :set_delivery, only: %i[show edit update destroy]
# GET /deliveries
# GET /deliveries.json
def index
#deliveries = Delivery.all
end
# GET /deliveries/1
# GET /deliveries/1.json
def show; end
# GET /deliveries/new
def new
#delivery = Delivery.new
#delivery.build_delivery_order
#delivery_orders = Order.all
end
# GET /deliveries/1/edit
def edit; end
# POST /deliveries
# POST /deliveries.json
def create
#delivery = current_manager.warehouse.deliveries.build(delivery_params)
respond_to do |format|
if #delivery.save
format.html { redirect_to #delivery, notice: 'Delivery was successfully created.' }
format.json { render :show, status: :created, location: #delivery }
else
format.html { render :new }
format.json { render json: #delivery.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /deliveries/1
# PATCH/PUT /deliveries/1.json
def update
respond_to do |format|
if #delivery.update(delivery_params)
format.html { redirect_to #delivery, notice: 'Delivery was successfully updated.' }
format.json { render :show, status: :ok, location: #delivery }
else
format.html { render :edit }
format.json { render json: #delivery.errors, status: :unprocessable_entity }
end
end
end
# DELETE /deliveries/1
# DELETE /deliveries/1.json
def destroy
#delivery.destroy
respond_to do |format|
format.html { redirect_to deliveries_url, notice: 'Delivery was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_delivery
#delivery = Delivery.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def delivery_params
params.require(:delivery).permit(:delivery_date, :delivery_on_time, delivery_order_attributes: %i[order_1 order_2 order_3 order_4 delivery_id order_id], orders_attributes: [:order_id])
end
end
delivery _form.html.erb
<div class="container">
<%= simple_form_for(#delivery) do |f| %>
<%= f.error_notification %>
<div class="form-group">
<label>Estimated Delivery Date</label>
<%= f.input :delivery_date, class: 'form-control', label: false %>
</div>
<%= simple_fields_for :delivery_order, #delivery.delivery_order do |d| %>
<div class="form-control">
<label>Delivery Order 1</label>
<%= d.input :order_1, collection: #delivery_orders, :label_method => lambda {|order| "Order Id: #{order.id} | Client Name: #{order.client_name} | Client Address: #{order.client_address} | Bread Type: #{order.bread_type} | Bread Quantity: #{order.bread_quantity}" }, value_method: :id, include_blank: false, prompt: 'Add your first order to the delivery', class: 'form-control', label: false %>
</div>
<div class="form-group">
<label>Delivery Order 2</label>
<%= d.input :order_2, collection: #delivery_orders, :label_method => lambda {|order| "Order Id: #{order.id} | Client Name: #{order.client_name} | Client Address: #{order.client_address} | Bread Type: #{order.bread_type} | Bread Quantity: #{order.bread_quantity}" }, value_method: :id, include_blank: false, prompt: 'Add your second order to the delivery', class: 'form-control', label: false %>
</div>
<div class="form-group">
<label>Delivery Order 3</label>
<%= d.input :order_3, collection: #delivery_orders, :label_method => lambda {|order| "Order Id: #{order.id} | Client Name: #{order.client_name} | Client Address: #{order.client_address} | Bread Type: #{order.bread_type} | Bread Quantity: #{order.bread_quantity}" }, value_method: :id, include_blank: false, prompt: 'Add your third order to the delivery', class: 'form-control', label: false %>
</div>
<div class="form-group">
<label>Delivery Order 4</label>
<%= d.input :order_4, collection: #delivery_orders, :label_method => lambda {|order| "Order Id: #{order.id} | Client Name: #{order.client_name} | Client Address: #{order.client_address} | Bread Type: #{order.bread_type} | Bread Quantity: #{order.bread_quantity}" }, value_method: :id, include_blank: false, prompt: 'Add your fourth order to the delivery', class: 'form-control', label: false %>
</div>
<% end %>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
</div>
orders _form.html.erb
<%= simple_form_for(#order) do |f| %>
<%= f.error_notification %>
<div class="form-group">
<label>Name</label>
<%= f.input :client_name, required: true, label: false, class: 'form-control' %>
</div>
<div class="form-group">
<label>Zip Code</label>
<%= f.input :client_zip_code, required: true, label: false, class: 'form-control' %>
</div>
<div class="form-group">
<label>Address</label>
<%= f.input :client_address, required: true, label: false, class: 'form-control' %>
</div>
<div class="form-group">
<label>State</label>
<%= f.input :client_state, required: true, label: false, class: 'form-control' %>
</div>
<div class="form-group">
<label>Choose a Bread</label>
<%= f.collection_select :bread_name, collection: Bread.all, required: true, label: false, class: 'form-control' %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
trucks_controller.rb
class TrucksController < ApplicationController
before_action :set_truck, only: %i[show edit update destroy]
before_action :authenticate_manager!
# GET /trucks
# GET /trucks.json
def index
#trucks = Truck.all
end
# GET /trucks/1
# GET /trucks/1.json
def show;
end
# GET /trucks/new
def new
#truck = Truck.new
#deliveries = Delivery.all
end
# GET /trucks/1/edit
def edit;
end
# POST /trucks
# POST /trucks.json
def create
#truck = current_manager.warehouse.trucks.build(truck_params)
respond_to do |format|
if #truck.save
format.html {redirect_to #truck, notice: 'Truck was successfully created.'}
format.json {render :show, status: :created, location: #truck}
else
format.html {render :new}
format.json {render json: #truck.errors, status: :unprocessable_entity}
end
end
end
# PATCH/PUT /trucks/1
# PATCH/PUT /trucks/1.json
def update
respond_to do |format|
if #truck.update(truck_params)
format.html {redirect_to #truck, notice: 'Truck was successfully updated.'}
format.json {render :show, status: :ok, location: #truck}
else
format.html {render :edit}
format.json {render json: #truck.errors, status: :unprocessable_entity}
end
end
end
# DELETE /trucks/1
# DELETE /trucks/1.json
def destroy
#truck.destroy
respond_to do |format|
format.html {redirect_to trucks_url, notice: 'Truck was successfully destroyed.'}
format.json {head :no_content}
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_truck
#truck = Truck.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def truck_params
params.require(:truck).permit(:delivery_total, :lon, :lat, :delivery_id, :loaded_date, :truck_driver_name, :current_street_address, :current_city, :current_state, :current_country)
end
end
truck.rb
class Truck < ApplicationRecord
belongs_to :warehouse, optional: true
has_many :deliveries
end
trucks _form.html.erb
<div class="container">
<%= simple_form_for(#truck) do |f| %>
<%= f.error_notification %>
<div class="form-group">
<div class="col-3">
<label>Loaded Date (Click Box Below)</label>
<%= f.input :loaded_date, as: :date_time_picker, class: 'form-control', placeholder: "Tap to view calendar <i class: 'fa fa-hand-o-up'></i>", label: false %>
</div>
</div>
<div class="form-group">
<div class="col-5">
<%= f.input :delivery_total, class: 'form-control' %>
</div>
</div>
<div class="form-group">
<div class="col-5">
<%= f.input :truck_driver_name, class: 'form-control btn btn-outline-primary' %>
</div>
</div>
<div class="form-group">
<div class="col-5">
<%= f.input :current_street_address, class: 'form-control' %>
</div>
</div>
<div class="form-group">
<div class="col-5">
<%= f.input :current_city, class: 'form-control' %>
</div>
</div>
<div class="form-group">
<div class="col-5">
<%= f.input :current_state, class: 'form-control' %>
</div>
</div>
<div class="form-group">
<div class="col-5">
<%= f.input :current_country, class: 'form-control' %>
</div>
</div>
<div class="form-group">
<div class="col-5">
<%= f.input :delivery_id, collection: #deliveries, :label_method => lambda {|delivery| "Estimated Delivery Date: #{delivery.delivery_date} | Order Id: #{delivery.id}"}, value_method: :id, label: "Delivery Jobs", include_blank: false, prompt: 'Add a delivery to the truck' %>
</div>
</div>
<div class="form-actions">
<%= f.button :submit, class: 'btn btn-outline-success' %>
</div>
<% end %>
</div>

collection_select not inserting value from other model

I have two models, Roaster and Roast
I want to have the user select the value of :roaster in the new roast form, from the Roaster model. I am using a collection_select which displays the list of roasters in the dropdown ok, but it doesn't insert the value into the table. From the console, it actually looks like it's trying to pass the roaster_id
"roast"=>{"roaster_id"=>"1", "name"=>"Rugby", "beans"=>"", "countries_attributes"=>{"0"=>{"country_name"=>"", "regions_attributes"=>{"0"=>{"region_name"=>""}}}, "1"=>{"country_name"=>"", "regions_attributes"=>{"0"=>{"region_name"=>""}}}, "2"=>{"country_name"=>"", "regions_attributes"=>{"0"=>{"region_name"=>""}}}}, "bestfor"=>"", "roast"=>"", "tastingnotes"=>""}, "commit"=>"Create Roast"}
My select:
<%= form.collection_select(:roaster_id, Roaster.all, :id, :roaster_name, :prompt => 'Select Roaster') %>
I've tried
<%= form.collection_select(:roaster_name, Roaster.all, :id, :roaster_name, :prompt => 'Select Roaster') %>
but this gives and undefined method error.
My roast_params
params.require(:roast).permit(:roaster, :roaster_id, :name, :bestfor, :beans, :roast, :tastingnotes, :notes, :slug, :avatar, countries_attributes: [:country_id, :country_name, regions_attributes: [:id, :region_name]])
Adding in :roaster_name doesn't solve either.
As requested full form:
<%= form_with(model: roast, local: true, multipart: true) do |form| %>
<% if roast.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger" role="alert">
<h2><%= pluralize(roast.errors.count, "error") %> prohibited this roast from being saved:</h2>
<ul>
<% roast.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
</div>
<% end %>
<form>
<div class="row">
<div class="col-6">
<div class="field form-group">
<%= form.label :roaster, class: 'control-label' %>
<%= form.collection_select(:roaster_id, Roaster.all, :id, :roaster_name, :prompt => 'Select Roaster') %>
</div>
</div>
<div class="col-6">
<div class="form-group">
<%= form.label :name, class: 'control-label' %>
<%= form.text_field :name, class: "form-control" %>
</div>
</div>
</div>
<div class="form-group">
<%= form.label :beans, "Blend", class: 'control-label' %><br />
<%= form.select :beans, [ 'Single Origin','Two Country Blend', 'Three Country Blend' ], :prompt => 'Select One', id: :roast_beans, class: "form-control" %>
</div>
<div class="row">
<%= form.fields_for :countries do |countries_form| %>
<div class="col-6">
<div class="form-group">
<%= countries_form.label :country %>
<%= countries_form.text_field :country_name, class: "form-control" %>
</div>
</div>
<div class="col-6">
<!-- note the appending of `countries_` to form.fields to allow for deeper nested to work-->
<%= countries_form.fields_for :regions do |regions_form| %>
<%= regions_form.label :region %>
<%= regions_form.text_field :region_name, class: "form-control" %>
<% end %>
<br />
</div>
<% end %>
</div>
<div class="form-group">
<%= form.label :bestfor, "Style", class: 'control-label' %><br />
<%= form.select :bestfor, [ 'Espresso','Filter' ], :prompt => 'Select One', id: :roast_bestfor, class: "form-control" %>
</div>
<div class="form-group">
<%= form.label :roast, "Strength", class: 'control-label' %><br />
<%= form.select :roast, [ 'Light','Medium','Dark' ], :prompt => 'Select One', id: :roast_roast, class: "form-control" %>
</div>
<div class="form-group">
<%= form.label :tastingnotes, "Tasting Notes (separate with commas, e.g chocolate, citrus)", class: 'control-label' %><br />
<%= form.text_area :tastingnotes, id: :roast_tastingnotes, class: "form-control" %>
</div>
<br />
<div class="form-group">
<%= form.label :avatar, "Upload image...", class: 'control-label' %>
<%= form.file_field :avatar %>
</div>
<div class="actions">
<%= form.submit class: "btn btn-success" %> <%= link_to "Cancel", "/roasts", class: "btn btn-secondary"%>
</div>
<% end %>
</form>
roast_controller.rb
class RoastsController < ApplicationController
before_action :set_roast, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, only: [:create, :edit, :update, :destroy]
before_action :set_search
# GET /roasts
# GET /roasts.json
def index
#q = Roast.ransack(params[:q])
#roastsalpha = #q.result.order(:name)
#roastcount = Roast.count(:country)
#roasts = Roast.order(:name).count
#countroastschart = Roast.order("roaster DESC").all
end
# GET /roasts/1
# GET /roasts/1.json
def show
#roast = Roast.friendly.find(params[:id])
#commentable = #roast
#comments = #commentable.comments
#comment = Comment.new
#sameroaster = Roast.where(roaster: #roast.roaster)
#samecountry = Roast.where(country: #roast.country)
#roastcount = Roast.where(roaster: #roast.roaster)
end
# GET /roasts/new
def new
#roast = Roast.new
3.times {#roast.countries.build.regions.build}
end
# GET /roasts/1/edit
def edit
3.times {#roast.countries.build.regions.build}
end
# POST /roasts
# POST /roasts.json
def create
#roast = Roast.new(roast_params)
respond_to do |format|
if #roast.save
format.html { redirect_to #roast, notice: 'Roast was successfully created.' }
format.json { render :show, status: :created, location: #roast }
else
format.html { render :new }
format.json { render json: #roast.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /roasts/1
# PATCH/PUT /roasts/1.json
def update
respond_to do |format|
if #roast.update(roast_params)
format.html { redirect_to #roast, notice: 'Roast was successfully updated.' }
format.json { render :show, status: :ok, location: #roast }
else
format.html { render :edit }
format.json { render json: #roast.errors, status: :unprocessable_entity }
end
end
end
# DELETE /roasts/1
# DELETE /roasts/1.json
def destroy
#roast.destroy
respond_to do |format|
format.html { redirect_to roasts_url, notice: 'Roast was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_roast
#roast = Roast.friendly.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def roast_params
params.require(:roast).permit(:roaster, :roaster_id, :name, :bestfor, :beans, :roast, :tastingnotes, :notes, :slug, :avatar, countries_attributes: [:country_id, :country_name, regions_attributes: [:id, :region_name]])
end
end
I think you are doing many wrong things. By looking your other questions I saw your models. I put some important things:
class Roast < ApplicationRecord
has_many :countries
accepts_nested_attributes_for :countries
end
class Country < ApplicationRecord
has_many :regions, inverse_of: :country
accepts_nested_attributes_for :regions
belongs_to :roast
end
class Region < ApplicationRecord
belongs_to :country, inverse_of: :regions
end
In these models I didn't see the Roaster. I assume a Roast belongs_to :roaster.
So: your Roast has many countries and each country has many regions. But you are passing country names and region names in your view to the create controller. You need to pass the ids, so that you save references to these models.
You have many unnecessary field in params, and some missing ones. This is how it should be:
def roaster_params
params.require(:roast).permit(:roaster_id, :name, :bestfor, :beans, :tastingnotes, :notes, :slug, :avatar, countries_attributes: [:id, regions_attributes: [:id]])
end
You don't need roast, roaster, country_name, region_name. You need the id of the country (and not the country_id), and the id of the region (and not the region_id)
In your form you should ask for country and region ids:
<%= countries_form.collection_select(:id, Country.all, :id, :name, :prompt => 'Select Country') %>
<%= regions_form.collection_select(:id, Region.all, :id, :name, :prompt => 'Select Region') %>
In fact this is more difficult, because a region belongs to a country, but here you are showing all regions. You should only show regions for the selected country (which is dynamic).

Show nested_fields in Rails 4

I have a weird problem with "nested_form" in Rails. I made a model "evaluate" associated to other model "proyect", but when I try to show theres fields, on "proyects" form, just show fields from "proyects".
Here is my code:
Models:
proyect.erb
class Proyect < ActiveRecord::Base
belongs_to :user
has_many :vercions #I know is versions
has_many :evaluates #I know is evaluators
accepts_nested_attributes_for :evaluates, allow_destroy: true
validates :titulo,:presence => true,
:length => { :minimum => 3 }
validates :descripcion,:presence => true,
:length => { :minimum => 3 }
end
evaluate.erb
class Evaluate < ActiveRecord::Base
belongs_to :proyect
has_and_belongs_to_many :users
end
Controller
proyects_controller.erb
class ProyectsController < ApplicationController
before_action :set_proyect, only: [:show, :edit, :update, :destroy]
# GET /proyects
# GET /proyects.json
def index
if current_user.tipo == 'i'
#proyects = Proyect.where(:user_id => current_user.id)
else
#proyects = #Proyect.where(:id_user => current_user.id)
Proyect.all
end
end
# GET /proyects/1
# GET /proyects/1.json
def show
#vercion = Vercion.new
end
# GET /proyects/new
def new
#proyect = Proyect.new
#proyect.evaluates.build
end
# GET /proyects/1/edit
def edit
end
# POST /proyects
# POST /proyects.json
def create
#proyect = current_user.proyects.new(proyect_params)
respond_to do |format|
if #proyect.save
format.html { redirect_to #proyect, notice: 'Proyecto creado!.' }
format.json { render :show, status: :created, location: #proyect }
else
format.html { render :new }
format.json { render json: #proyect.errors, status: :unprocessable_entity }
end
# Llamamos al ActionMailer que creamos
Usermailer.bienvenido_email(current_user,#proyect).deliver
end
end
# PATCH/PUT /proyects/1
# PATCH/PUT /proyects/1.json
def update
respond_to do |format|
if #proyect.update(proyect_params)
format.html { redirect_to #proyect, notice: 'Proyect was successfully updated.' }
format.json { render :show, status: :ok, location: #proyect }
else
format.html { render :edit }
format.json { render json: #proyect.errors, status: :unprocessable_entity }
end
end
end
# DELETE /proyects/1
# DELETE /proyects/1.json
def destroy
#proyect.destroy
respond_to do |format|
format.html { redirect_to proyects_url, notice: 'Proyect was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_proyect
#proyect = Proyect.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def proyect_params
params.require(:proyect).permit(
:titulo, :descripcion,:evaluador, :id_user, :codigo, :user_assign,evaluates_attributes: [:id,:nombre, :prioridad, :_destroy, user_ids: [] ])
end
end
Views
_form.html.erb (Proyects)
<%= nested_form_for(#proyect) do |f| %>
<% if #proyect.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#proyect.errors.count, "error") %> prohibited this proyect from being saved:</h2>
<ul>
<% #proyect.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :titulo %><br>
<%= f.text_field :titulo %>
</div>
<div class="field">
<%= f.label :descripcion %><br>
<%= f.text_area :descripcion %>
</div>
<div class="field">
<%= f.hidden_field :id_user, :value => current_user.id %>
</div>
<!--Aqui añadi algo-->
<fieldset id="evaluates">
<%= f.fields_for :evaluates do |evaluates_form| %>
<div class="field">
<%= evaluates_form.label :status %><br>
<%= evaluates_form.text_field :status %>
</div>
<%= evaluates_form.link_to_remove "Eliminar esta tarea" %>
<% end %>
<p><%= f.link_to_add "Agregar una tarea", :evaluates %></p>
</fieldset>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
_evaluate_fields.html.erb
<div class="field">
<%= f.label :status, 'Nombre de la tarea' %><br>
<%= f.text_field :status %>
</div>
<div class="field">
<%= f.collection_check_boxes :user_ids, User.where(:tipo => 'e'), :id, :cedula %>
</div>
<%= f.link_to_remove "Eliminar Evaluador" %>

First argument in form cannot contain nil or be empty

I receive this error with my Book form in rails:
First argument in form cannot contain nil or be empty
Form
<%= form_for #book, html: { multipart: true } do |f| %>
<% if #book.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#book.errors.count, "error") %> prohibited this book from being saved:</h2>
<ul>
<% #book.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :author %><br>
<%= f.text_field :author %>
</div>
<div class="field">
<%= f.label :language %><br>
<%= f.text_field :language %>
</div>
<div class="field">
<%= f.label :year %><br>
<%= f.text_field :year %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :total_pages %><br>
<%= f.text_field :total_pages %>
</div>
<div class="field">
<%= f.label :rating %><br>
<%= f.text_field :rating %>
</div>
<div class="field">
<%= f.label :image %><br>
<%= f.file_field :image %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Controller
class BooksController < ApplicationController
before_action :set_book, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def search
if params[:search].present?
#books = Book.search(params[:search])
else
#books = Book.all
end
end
def index
#books = Book.all
end
def show
#reviews = Review.where(book_id: #book.id).order("created_at DESC")
if #reviews.blank?
#avg_review = 0
else
#avg_review = #reviews.average(:rating).round(2)
end
end
end
def new
#book = current_user.books.build
end
def edit
end
def create
#book = current_user.books.build(book_params)
respond_to do |format|
if #book.save
format.html { redirect_to #book, notice: 'Book was successfully created.' }
format.json { render :show, status: :created, location: #book }
else
format.html { render :new }
format.json { render json: #book.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #book.update(book_params)
format.html { redirect_to #book, notice: 'Book was successfully updated.' }
format.json { render :show, status: :ok, location: #book }
else
format.html { render :edit }
format.json { render json: #book.errors, status: :unprocessable_entity }
end
end
end
def destroy
#book.destroy
respond_to do |format|
format.html { redirect_to books_url, notice: 'Book was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_book
#book = Book.find(params[:id])
end
def book_params
params.require(:book).permit(:title, :author, :language, :year, :description, :total_pages, :rating, :image)
end
I got related errors, but none of the solutions seems to fit my particular issue. Any clues to what could be causing this?
You're getting the error because #book is nil.
Make sure that you have initialized #book using #book = Book.new in the corresponding controller action so that #book is available to the view containing the form.
initialized #book = Book.new in the controller action

Resources