Couldn't find World with 'id'= - ruby-on-rails

I have a World parent object and a State child object. I'm trying to create a new State object and rails isn't finding the world id. I'm trying to link to the new state form from the world show page, and the url shows .../worlds/1/states/new so why is this not picking up on the parent id? The error is supposedly coming from this line in the controller #world = World.find(params[:id]). I have tried using (params[:world_id]) even.
For brevity I'm only posting the relevant code here.
world.rb
class World < ApplicationRecord
belongs_to :user
has_many :states
end
state.rb
class State < ApplicationRecord
belongs_to :world
belongs_to :user
end
states_controller.rb
class StatesController < ApplicationController
before_action :set_state, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
#states = State.all
end
def new
#world = World.find(params[:id])
#state = #world.states.build
end
def create
#world = World.find(params[:id])
#state = #world.states.build(state_params)
#state.user = current_user
respond_to do |format|
if #state.save
format.html { redirect_to #state, notice: 'State was successfully created.' }
else
format.html { render :new }
end
end
end
private
def set_state
#state = State.find(params[:id])
end
def state_params
params.require(:state).permit(:name, :summary, :history, :population, :inception, :life_expectancy, :land_mass,
:climate, :industry, :education, :mythology, :law, :culture, :world_id, :user_id)
end
end
The link to the new state form in worlds/show.html.erb:
<%= link_to 'New State', new_world_state_path(#world) %>
routes.rb
Rails.application.routes.draw do
resources :states
resources :worlds
devise_for :users, path: '', path_names: { sign_in: 'login', sign_out: 'logout', sign_up: 'register' }
root to: "home#index"
resources :users
resources :worlds do
resources :states
end
end
states/_form.html.erb
<div class="form">
<%= form_for(state) do |f| %>
<% if state.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(world.errors.count, "error") %> prohibited this state from being saved:</h2>
<ul>
<% state.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.text_field :name, placeholder: 'Name' %><br />
<fieldset>
<legend>Basic Info</legend>
<%= f.text_area :summary, placeholder: 'Summary About', rows: 6 %><br />
<%= f.text_area :history, placeholder: 'History', rows: 6 %><br />
<%= f.text_area :climate, placeholder: 'Climate', rows: 3 %><br />
<%= f.text_area :industry, placeholder: 'Industry', rows: 3 %><br />
<%= f.text_area :education, placeholder: 'Education', rows: 3 %><br />
<%= f.text_area :culture, placeholder: 'Culture', rows: 3 %><br />
<%= f.text_area :law, placeholder: 'Legal System, Crime & Punishment', rows: 3 %><br />
<%= f.text_area :mythology, placeholder: 'Mythology', rows: 3 %><br />
</fieldset>
<fieldset>
<legend>Quick Stats</legend>
<%= f.text_field :inception, placeholder: 'Inception' %><br />
<%= f.text_field :population, placeholder: 'Population' %><br />
<%= f.text_field :life_expectancy, placeholder: 'Ave. Life Expectance' %><br />
<%= f.text_field :land_mass, placeholder: 'Land Mass' %><br />
</fieldset>
<p><%= f.submit %></p>
<% end %>
</div>
rails console results when clicking 'New State' link
Started GET "/worlds/1/states/new" for 70.196.17.76 at 2017-05-22 13:43:47 +0000
Cannot render console from 70.196.17.76! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by StatesController#new as HTML
Parameters: {"world_id"=>"1"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
World Load (0.1ms) SELECT "worlds".* FROM "worlds" WHERE "worlds"."id" = ? LIMIT ? [["id", nil], ["LIMIT", 1]]
Completed 404 Not Found in 3ms (ActiveRecord: 0.4ms)
ActiveRecord::RecordNotFound (Couldn't find World with 'id'=):
app/controllers/states_controller.rb:13:in `new'
Rendering /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.3/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout
Rendering /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.3/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.3/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (4.7ms)
Rendering /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.3/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.3/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.6ms)
Rendering /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.3/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.3/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.1ms)
Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.3/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (36.6ms)

Modify your link_to helper to specify and tell to Rails what's the parameter you're sending through it:
From:
<%= link_to 'New State', new_world_state_path(#world) %>
To:
<%= link_to 'New State', new_world_state_path(id: #world) %>
id because you're trying to find the World through :id as param.
Try also changing the param that's being received within the controller where you're setting the #world variable:
def new
#world = World.find(params[:world_id])
...
end
In the show.html.erb:
<%= link_to 'New World', new_world_state_path(world_id: #world) %>
Update: What we made:
In the app/views/worlds/show.html.erb to change the way the param was being setted:
From:
<%= link_to 'New Nation', new_world_state_path(world_id: #world_id) %> # #world_id wasn't defined
To:
<%= link_to 'New Nation', new_world_state_path(world_id: #world.id) %>
In the /app/views/states/_form.html.erb to add the world_id as a hidden_field:
<%= f.hidden_field :world_id, value: #world.id %>
And then in app/controllers/states_controller.rb to change the way the params were being received:
def new
#world = World.find(params[:world_id])
#state = #world.states.build
end
def create
#world = World.find(params[:state][:world_id])
...

The world_id while it is passed to the :new action, it may not be passed back on the form to the create action.
Your state_params are expecting a :world_id to be sent back so add a hidden field to send it back on the form.
new.html.erb
<%= f.hidden_field :world_id, :value => #world.id %>
and update the create action to
#world = World.find(params[:world_id])

Related

Rails Params returning a nil value. I can't pass in value via controller or form?

I have tried a few methods and checked all of the existing SO questions I can find and can't find an answer to the problem. I'm a Rails newbie.
I have these models:
Project (has_many WeeklyReflections, has_many ProjectTasks)
WeeklyReflection (belongs_to Project)
ProjectTask (belongs_to Project)
Standard devise user model
My Project show page displays a list of ProjectTasks for the week. Using simplecalendar.
I can navigate forward and back a week at a time, which then changes the URL from www.site.com/projects/3 to www.site.com/projects/3?start_date=2108-05-30, or www.site.com/projects/3?start_date=2108-05-13, and this then shows all the tasks related to that week.
What I want to do as well, is for each page create a weekly journal entry, only one of which can be created for the week, however, I'm having problems saving it to my controller - I've tried a few ways and also tried putting it in as a hidden field on a form, and still can't get it to work.
I've put start_date:<%= render inline: params[:start_date].inspect %> on both the Project show page and form it returns a value correctly, i.e. "start_date:"2018-04-28"" or it returns nil if on the default show page which is to be expected.
The two methods I've tried: are - accessing the start_date param via the controller (in the controller below) and also adding the following to the form:
<%= hidden_field_tag(:weekending, params[:start_date]) %> (I've also tried using .to_date, as I think the string it returns isn't in the right format)
However, both methods are returning a nil value when the start_date param is returning 2018-04-28 on the view page.
Console log after create action:
Started POST "/projects/6/weekly_reflections" for 2.96.199.78 at 2018-05-07 16:20:14 +0000
Cannot render console from 2.96.199.78! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by WeeklyReflectionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"UFCXjIp1SZrql2JckHk1HrzDlzO2/WLVwcdvdh+FQKbdrVMfdaivtjS32oLaFwcFs0UcupVP+XV6VVnNwrM0XQ==", "week_reflection"=>{"reflectionentry"=>"adasda", "motivationscore"=>"1", "beliefscore"=>"1"}, "weekending"=>"2018-04-28", "commit"=>"Create Project reflection", "project_id"=>"6"}
Project Load (0.6ms) SELECT "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT ? [["id", 6], ["LIMIT", 1]]
(0.1ms) begin transaction
(0.1ms) commit transaction
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]]
(0.1ms) begin transaction
SQL (1.3ms) INSERT INTO "week_reflections" ("reflectionentry", "user_id", "project_id", "motivationscore", "beliefscore", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?) [["reflectionentry", "adasda"], ["user_id", 2], ["project_id", 6], ["motivationscore", 1], ["beliefscore", 1], ["created_at", "2018-05-07 16:20:14.957131"], ["updated_at", "2018-05-07 16:20:14.957131"]]
(15.0ms) commit transaction
-
class WeeklyReflectionsController < ApplicationController
before_action :set_weekly_reflection, only: [:show, :edit, :update, :destroy]
before_action :set_project, only: [:new, :edit, :create, :show]
def index
#weekly_reflections= WeeklyReflection.all
end
def new
#weekly_reflection= WeeklyReflection.new
end
def create
#weekly_reflection= #project.weekly_reflections.create(project_reflection_params)
#weekly_reflection.user = current_user
#weekly_reflection.weekending = params[:start_date].to_date || Date.today.beginning_of_week
respond_to do |format|
if #weekly_reflections.save
format.html { redirect_to #weekly_reflection.project, notice: 'Weekly reflection was successfully created.' }
else
format.html { redirect_to #weekly_reflection.project, notice: 'Weekly reflection could not be added.' }
end
end
end
private
def weekly_reflection
#weekly_reflection= WeeklyReflection.find(params[:id])
end
def set_project
#project = Project.find(params[:project_id])
end
def weekly_reflection_params
params.require(:weekly_reflection).permit(:reflectionentry, :weekending, :motivationscore, :beliefscore)
end
end
Project show page:
<p id="notice"><%= notice %></p>
start_date:<%= render inline: params[:start_date].inspect %>
<div class="row well">
<div class="col-md-12">
<%= render 'project_detail' %>
</div>
<div class="col-md-12">
<% if #project.user == current_user && #project.active? %>
<br>
<%= render "project_tasks/task_modal" %>
<% end %>
</div>
<div class="col-md-12">
<%= render "project_reflection_calendar" %>
<% if #project.user == current_user && #project.active? %>
<h3>Add your thoughts for this week</h3>
<%= render "project_reflections/form_reflection" %>
<% end %>
</div
WeeklyEntry form, shown on the project show page:
<div class="row">
start_date:<%= render inline: params[:start_date].inspect %>
<%= form_for([#project, #project.weekly_reflections.build]) do |form| %>
<div class="col-md-12 projectform">
<%= form.label "Add your thoughts for this week" %>
<%= form.text_field :reflectionentry, :rows =>2, style: 'width:100%;' %>
</div>
<div class="col-md-7 projectform">
<%= form.label "How motivated are you for your project this week?" %>
<%= form.select :motivationscore, [1,2,3,4,5,6,7,8,9,10], class:"form-control" %>
</div>
<div class="col-md-7 projectform">
<%= form.label "How strongly do you believe you will reach your project?" %>
<%= form.select :beliefscore, [1,2,3,4,5,6,7,8,9,10], class:"form-control" %>
</div>
<%= hidden_field_tag(:weekending, params[:start_date].to_date) %>
<div class="col-md-12 projectform">
<%= form.submit class:"btn btn-primary" %>
</div>
<% end %>
</div>
ApplicationRecord code:
class WeeklyReflection < ApplicationRecord
belongs_to :project
belongs_to :user
validates :reflectionentry, presence:true, length: {minimum:3, maximum: 540}
#required for simple_calendar
def start_time
self.weekending
end
end
class Project < ApplicationRecord
has_many :project_tasks, dependent: :destroy
belongs_to :user
has_many :weekly_reflections, dependent: :destroy
end
=> WeeklyReflection Schema:
(id: integer, reflectionentry: text, user_id: integer, project_id: integer, weekending: date, motivationscore: integer, beliefscore: integer, created_at: datetime, updated_at: datetime)
I think, this should work:
Add to your ProjectController show action:
#weekly_reflection= #project.weekly_reflections.new
Change in WeeklyReflectionsController:
def create
#weekly_reflection = #project.weekly_reflections.new(weekly_reflection_params)
#weekly_reflection.user = current_user
respond_to do |format|
if #weekly_reflections.save
format.html { redirect_to #weekly_reflection.project, notice: 'Weekly reflection was successfully created.' }
else
format.html { redirect_to #weekly_reflection.project, notice: 'Weekly reflection could not be added.' }
end
end
end
private
def weekly_reflection_params
params.require(:weekly_reflection).permit(:reflectionentry, :weekending, :motivationscore, :beliefscore)
end
Change in WeeklyReflection form:
<div class="row">
<%= form_for #weekly_reflection do |form| %>
<div class="col-md-12 projectform">
<%= form.label "Add your thoughts for this week" %>
<%= form.text_field :reflectionentry, :rows =>2, style: 'width:100%;' %>
</div>
<div class="col-md-7 projectform">
<%= form.label "How motivated are you for your project this week?" %>
<%= form.select :motivationscore, [1,2,3,4,5,6,7,8,9,10], class:"form-control" %>
</div>
<div class="col-md-7 projectform">
<%= form.label "How strongly do you believe you will reach your project?" %>
<%= form.select :beliefscore, [1,2,3,4,5,6,7,8,9,10], class:"form-control" %>
</div>
<%= form.hidden_field :weekending, value: params[:start_date] || Date.today.beginning_of_week %>
<div class="col-md-12 projectform">
<%= form.submit class:"btn btn-primary" %>
</div>
<% end %>
</div>
Here we create #weekly_reflection variable inside the show action of ProjectsController, and just use it in form
That worked. Thanks so much.
With just a slight change to:
<%= form_for([#weekly_reflection.project, #weekly_reflection]) do |form| %>
I also had to add in:
<%= form.hidden_field :weekending, value: params[:start_date].try(:to_date).try(:beginning_of_week) || Date.today.beginning_of_week %>
So that I could capture the beginning of the week of the date in the param.

Rails: When I click on edit in my partial it always edits the same id

I'm a newbie and as you will probably see from my files, I don't fully know what I'm doing :( . At the moment I have a user and a project model. A project belongs to a user, a user has many projects.
I have created a user profile page that shows all projects belonging to that user. I would like to give the user the chance to edit or delete the project directly from his profile. At the moment Delete seems to work and Edit only works if the user first clicks on "show" and then edits the project. But when the user clicks on edit from his profile, the project to be edited is not the one clicked.
This is my profile view (views/users/show):
<% provide(:title, #user.name) %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<h1>
<%= #user.name %>
</h1>
</section>
</aside>
<div class="col-md-8">
<% if #user.projects.any? %>
<h3>Projects (<%= #user.projects.count %>)</h3>
<ol class="projects">
<%= render #projects %>
</ol>
<%= will_paginate #projects %>
<% end %>
</div>
</div>
This is the _project partial with the edit link:
<li id="project-<%= project.id %>">
<span class="title">
Title: <%= project.title %></span><br>
<span class="status">
<span class="user">
Submitted By: <%= link_to project.user.name, project.user %></span><br>
<span class="description">
Description: <%= project.description %></span><br>
<span class="status">
Status:<%= project.status %></span><br>
<span class="p_type">
Type: <%= project.p_type %></span><br>
<span class="timestamp">
Updated: <%= time_ago_in_words(project.updated_at) %> ago.
<% if current_user?(project.user) %>
<%= link_to "delete", project, method: :delete,
data: { confirm: "You sure?" } %>
<%= link_to "edit", edit_project_path %>
<%= link_to "New Project!", new_project_path %>
<% end %>
<!-- <%= link_to "show", project, method: :get %> -->
</span>
</li>
This is my projects controller:
class ProjectsController < ApplicationController
before_action :logged_in_user, only: [:create, :edit, :destroy]
before_action :correct_user, only: [:edit, :destroy]
def index
#projects = Project.paginate(page: params[:page])
end
def show
#project = Project.find(params[:id])
end
def new
#project = Project.new
end
def create
#project = current_user.projects.build(project_params)
if #project.save
flash[:success] = "Project created!"
redirect_to root_url
else
#feed_items = []
render 'new'
end
end
def edit
#project = Project.find params[:id]
end
def update
#project = Project.find params[:id]
#user = User.find(params[:id])
if #project.update(project_params)
flash[:success] = "Project updated"
redirect_to user_path(#user)
else
render 'edit'
end
end
def destroy
#project.destroy
flash[:success] = "Project deleted"
redirect_to request.referrer || root_url
end
private
def project_params
params.require(:project).permit(:description, :title, :status, :p_type)
end
def correct_user
#project = current_user.projects.find_by(id: params[:id])
redirect_to root_url if #project.nil?
end
end
My project model:
class Project < ApplicationRecord
belongs_to :user
default_scope -> { order(updated_at: :desc) }
validates :user_id, presence: true
validates :description, presence: true, length: { maximum: 250 }
validates :title, presence: true, length: { maximum: 60 }
validates :p_type, presence: true
validates :status, presence: true
end
My routes file:
Rails.application.routes.draw do
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :users
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :projects
end
Lastly if it helps, when I do the edit operation, this is the trace:
Started GET "/projects/1/edit" for 86.44.57.230 at 2016-10-29 12:16:49 +0000
Cannot render console from 86.44.57.230! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by ProjectsController#edit as HTML
Parameters: {"id"=>"1"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
Project Load (0.2ms) SELECT "projects".* FROM "projects" WHERE "projects"."user_id" = ? AND "projects"."id" = ? ORDER BY "projects"."updated_at" DESC LIMIT ? [["user_id", 1], ["id", 1], ["LIMIT", 1]]
Project Load (0.2ms) SELECT "projects".* FROM "projects" WHERE "projects"."id" = ? ORDER BY "projects"."updated_at" DESC LIMIT ? [["id", 1], ["LIMIT", 1]]
Rendering projects/edit.html.erb within layouts/application
Rendered shared/_error_messages.html.erb (0.6ms)
Rendered projects/edit.html.erb within layouts/application (24.9ms)
Rendered layouts/_shim.html.erb (0.4ms)
Rendered layouts/_header.html.erb (1.0ms)
Rendered layouts/_footer.html.erb (0.4ms)
Completed 200 OK in 179ms (Views: 172.4ms | ActiveRecord: 0.7ms)
Also adding the edit form
<% provide(:title, "Edit Project") %>
<h1>Update your Project</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#project) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :title %>
<%= f.text_field :title, class: 'form-control' %>
<%= f.label :p_type %>
<%= f.select :p_type, ([['QuickWin', 'QuickWin'],
['Project', 'Project']]) %>
<%= f.label :status %>
<%= f.select :status, ([['Not Yet Started', 'Not Yet Started'],
['In Progress', 'In Progress'], ['In Testing', 'In Testing'],
['On Hold', 'On Hold'], ['Launched', 'Launched']]) %>
<div class="field">
<%= f.text_area :description, placeholder: "Briefly summarise the purpose of this project..." %>
</div>
<%= f.submit "Save changes", class: "btn btn-primary" %>
<% end %>
</div>
</div>
Thank you in advance for your help!
On the below row is missing what is the record you wanna change:
<%= link_to "edit", edit_project_path %>
Add to 'edit_project_path' the project reference:
<%= link_to 'edit', edit_project_path(project) %>
I hope this help you.
...
About the error "Couldn't find User with 'id'=424" on call #user = User.find(params[:id]) on your comment ...
When you click on submit you send a PUT action on controller projects_controller.rb on method update with params with a Project object.
In your projects_controller.rb, your method 'update' receive a Project object.
Here params must appear as
params = { ... project:{:title => '...' , :ptype => ..}, 'id' => XXX }
this 'id' is the project.id !!
projects_controller.rb file
def update
#project = Project.find params[:id]
#user = User.find(params[:id]) <= you try to find a User with project.id
I think you wanna find user in join with this 'project'.
#user = #project.user

Rendering a nested partial template - to rended a nested form on a two separate models

I'm on week two of this issue and have recently used the railsCast #196 (revised). I know this is older - maybe that's my issue. As an extra spin I'm hosting my rails server off Cloud 9.
I've tried following a few different tutorials just to get one going & this is as far as I've gotten. The weird part is none of their syntex matches what the official ruby on rails documentation has ... Rails View templates.
In the railsCast the guy is able to get blank fields to show up ... I'm not sure how...so I haven't managed to populate the question or answer fields yet. I'm not even sure what the two rails console messages mean - besides there aren't records there to be had.
Thanks for reading & any suggestions!
-M
Without further ado, my senario ... nested forms via templates as shown in railsCast 196 ...
My rails console ...
2.2.1 :045 > cc = Survey.first.questions.first
Survey Load (0.5ms) SELECT "surveys".* FROM "surveys" ORDER BY "surveys"."id" ASC LIMIT 1
Question Load (0.2ms) SELECT "questions".* FROM "questions" WHERE "questions"."survey_id" = ? ORDER BY "questions"."id" ASC LIMIT 1 [["survey_id", 1]]
=> nil
2.2.1 :046 > cc = Survey.first.questions
Survey Load (0.3ms) SELECT "surveys".* FROM "surveys" ORDER BY "surveys"."id" ASC LIMIT 1
Question Load (0.2ms) SELECT "questions".* FROM "questions" WHERE "questions"."survey_id" = ? [["survey_id", 1]]
=> #<ActiveRecord::Associations::CollectionProxy []>
My terminal console log ...
Started GET "/surveys/5/edit" for 68.54.21.200 at 2015-11-27 02:46:48 +0000
Cannot render console from 68.54.21.200! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by SurveysController#edit as HTML
Parameters: {"id"=>"5"}
Survey Load (0.4ms) SELECT "surveys".* FROM "surveys" WHERE "surveys"."id" = ? LIMIT 1 [["id", 5]]
Question Load (0.2ms) SELECT "questions".* FROM "questions" WHERE "questions"."survey_id" = ? [["survey_id", 5]]
Rendered surveys/_form.html.erb (4.2ms)
Rendered surveys/edit.html.erb within layouts/application (7.3ms)
Completed 200 OK in 70ms (Views: 67.9ms | ActiveRecord: 0.5ms)
So my code ...
surveys_controller.rb
class SurveysController < ApplicationController
def index
#surveys = Survey.all
end
def show
#survey = Survey.find(params[:id])
end
def new
#survey = Survey.new
3.times do
question = #survey.questions.build
4.times { question.answers.build }
end
end
def create
#survey = Survey.new(survey_params)
if #survey.save
flash[:notice] = "Successfully created survey."
redirect_to #survey
else
render :action => 'new'
end
end
def edit
#survey = Survey.find(params[:id])
end
def update
#survey = Survey.find(params[:id])
if #survey.update_attributes(params[:survey])
flash[:notice] = "Successfully updated survey."
redirect_to #survey
else
render :action => 'edit'
end
end
def destroy
#survey = Survey.find(params[:id])
#survey.destroy
flash[:notice] = "Successfully destroyed survey."
redirect_to surveys_url
end
private
def survey_params
params.required(:survey).permit(:id, :survey, :notice)
end
end
Edit action view
<% title = "Edit Survey" %>
<%= render 'form' %>
<p>
<%= link_to "Show", #survey %> |
<%= link_to "View All", surveys_path %>
</p>
_form.html.erb
<%= form_for(#survey) do |f| %>
<% if #survey.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#survey.errors.count, "error") %> prohibited this survey from being saved:</h2>
<ul>
<% #survey.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<% f.fields_for :questions do |builder| %>
<%= render "question_fields", :f => builder %>
<% end %>
<p><%= f.submit "Submit" %></p>
<% end %>
_question_fields.html.erb
<p>
<%= f.label :content, "Question" %><br />
<%= f.text_area :content, :rows => 3 %><br />
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove Question" %>
</p>
<% f.fields_for :answers do |builder| %>
<%= render 'answer_fields', :f => builder %>
<% end %>
_answer_fields.html.erb
<p>
<%= f.label :content, "Answer" %>
<%= f.text_field :content %>
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove" %>
</p>
In each of the 7 projects I ran off the web...
It was the nesting of the array's within the params.require() that was the problem.. It's one thing to tell someone it has to be nested - it's another to show them the syntax when they are new :)
Example:
// Note this is from memory, as I deleted this version of the github..so it's not exactly right or tested...
params.require(:survey).permit(:id,:questions => [:id, :survey_id, :question, :answers => [:id, :question_id, :answer]])
Here's the break down of that same example in depth:
params.require(:survey).permit(
:id,
:questions => [:id, // This is the 1st nesting
:survey_id, :question, :answers => [:id, // This is 1st nested array ":questions"
:question_id, :answer] // End the 2nd nested array ":answers"
] // End the 2nd array ":questions"
) // End the ":surveys" array & the .permit as a whole

Rails ajax form for products

I've been working with app for pizzeria where customers could order pizzas through their website. I currently working with the product page where I try to submit products to shopping cart through ajax, but I'm really stuck. I haven't been able to build a shoppingcart which would accept product-id, product-size-id, extra-toppings as an array and quantity. I decided to try to go with session-store where all the order-row ids are stored and on menu page every product has a form where user could add product, size and quantity to shoppingcart but I keep getting this error in server logs:
Started POST "/order_row" for ::1 at 2015-08-03 11:18:21 +0300
Processing by OrderRowsController#create as JS
Parameters: {"utf8"=>"✓", "order_row"=>{"product"=>"1", "size"=>"0", "quantity"=>"2"}, "commit"=>"Tilaa"}
Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms)
ActiveRecord::AssociationTypeMismatch (Product(#70158072501800) expected, got String(#70158039566200)):
app/controllers/order_rows_controller.rb:4:in `create'
I have models Product, ProductCategory, Order, OrderRow and my session stores order-row-ids as mentioned. My menu page is actually product_categories#show -view where products belonging to that category are listed.
#order_rows_controller.rb
class OrderRowsController < ApplicationController
respond_to :html, :js
def create
#orow = OrderRow.new(order_rows_params)
if #orow.save
session[:order_row_ids] << #orow.id
flash[:notice] = "Lisättiin ostoskoriin!"
else
flash[:error] = "Tuotteen lisääminen ostoskoriin epäonnistui."
redirect :back
end
end
def update
#orow = OrderRow.find(params[:id])
if #orow.update_attributes(params[:order_row])
flash[:notice] = "Ostoskori päivitetty."
else
flash[:error] = "Ostoskorin päivitys epäonnistui."
end
end
def destroy
#orow.find(params[:id]).destroy
flash[:notice] = "Tuote poistettu onnistuneesti"
end
private
def order_rows_params
params.require(:order_row).permit(:product, :size, :quantity) #, :extras => []
end
end
ProductCategories-controller
class ProductCategoriesController < ApplicationController
before_action :set_product_category, only: [:edit, :update, :destroy]
respond_to :html, :js
def index
#product_categories = ProductCategory.all
end
def show
#product_category = ProductCategory.friendly.find(params[:id])
#product_categories = ProductCategory.all
#products = #product_category.products
#order_row = OrderRow.new(order: nil, product: nil, size: nil, extras: nil, quantity: nil)
end
And menu-page in product_categories/show.html.erb
#product_categories#show -view
<!--- category descriptions -->
<div class="container">
<% #products.each do |product| %>
<div class="col-sm-6 col-md-4">
<div class="product well">
<h3><%= product.name %></h3>
<span><%= product.description %></span>
<p class="prices">
<%= price(product.normal_price) %> | <%= price(product.plus_size_price) %> | <%= price(product.lunch_price) %>
</p>
<br>
<div id="form-<%= product.id %>">
<%= simple_form_for #order_row, :url => url_for(:controller => 'order_rows', :action => 'create'), remote: true do |f| %>
<%= f.hidden_field :product, :value => product.id %>
<h5>Koko</h5>
<div style="padding-left: 13px">
<%= f.input :size, collection: OrderRow.sizes, as: :radio_buttons, label: false, item_label_class: "radio-inline", item_wrapper_tag: false %>
</div>
<h5>Määrä</h5>
<div style="width: 8%; padding-left: 13px;">
<%= f.input :quantity, as: :string, label: false %>
</div>
<p>
<%= f.submit "Tilaa", class: "btn btn-success btn-lg" %>
</p>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
Create.js.erb in order_rows#create action
#create.js.erb
$("#form-<%= params[:product] %>").load(document.URL + "#form-<%= params[:product]");
Associations:
#order_row
belongs_to :order
belongs_to :product
#product
belongs_to :product_category
has_one :campaign_producte
belongs_to :dish_type
#product_categories
has_many :products
has_many :campaign_products
has_many :product_extras
has_many :dish_types, through: :products
#product_extra
belongs_to :product_category
Link to github-repo: https://github.com/casualCodeAndDesign/ravintolamammamia
What's the reason for this server error and why it doesn't store my order_row to the database?
ActiveRecord::AssociationTypeMismatch (Product(#70158072501800)
expected, got String(#70158039566200))
You need to change
<%= f.hidden_field :product, :value => product.id %>
to
<%= f.hidden_field :product_id, :value => product.id %>
and product to product_id in create.js.erb and order_rows_params

Wicked Gem, associated models param is missing

I have a Boat model and Location Model. Boat has_one :location, Location belongs_to :boat. I used wicked gem to update the models. But I am having an issue in boat_steps_controller's #update action.
Here is my boat_steps_controller,
class BoatStepsController < ApplicationController
include Wicked::Wizard
before_action :logged_in_user
steps :model, :pricing, :description, :picture, :overview, :features, :location
def show
#boat = current_user.boats.find(params[:boat_id])
case step
when :location
#location = #boat.build_location
when :picture
#picture = #boat.pictures.new
#pictures = #boat.pictures.all
end
render_wizard
end
def update
#boat = current_user.boats.find(params[:boat_id])
#boat.update(boat_params)
case step
when :picture
#picture.update(picture_params)
when :location
#location.update(location_params)
end
render_wizard #boat
end
private
def boat_params
params.require(:boat).permit(:brand, :year, :model, .....)
end
def picture_params
params.require(:picture).permit(:name, :boat_id, :image)
end
def location_params
params.require(:location).permit(:address, :longitude, :latitude, :formatted_address, :location_type)
end
end
The problem here is that, in #update action, I update boat_params in every step. But in Location, there is no boat_params to update as it is a associated model. So I have to find a way either get the boat id from the form or put if statement.
Here is the location.html.erb (form for wicked gem)
<%= form_for [#boat, #location], url: wizard_path, method: :put do |f| %>
<div class="field">
<%= f.label :address %><br>
<%= f.text_field :address,:id => "geocomplete", :value => "Ataköy Marina, 34140 Bakırköy/İstanbul, Türkiye" %>
</div>
<div class="field">
<%= f.label :longitude %><br>
<%= f.text_field :longitude, :name => "lng", :readonly => "readonly" %>
</div>
<div class="field">
<%= f.label :latitude %><br>
<%= f.text_field :latitude, :name => "lat", :readonly => "readonly" %>
</div>
<div class="field">
<%= f.label :formatted_address %><br>
<%= f.text_field :formatted_address, :name => "formatted_address", :readonly => "readonly" %>
</div>
<div class="actions">
<%= f.submit "Finish" ,class: "btn btn-primary" %>
</div>
<% end %>
It should normally send boat id as I use [#boat, #location], the url becomes, http://localhost:3000/boats/241/boat_steps/location. But when I post this, I get an error of;
Started PUT "/boats/241/boat_steps/location" for ::1 at 2015-05-12 10:00:21 +0300
Processing by BoatStepsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"jJOEBSCe9WdcuMKiHeVnh9zFEYuu15L5tzIkNFo9cED7ToG0MHq8jqeGstq5krdRGnrNXayNTQI0fajjHsNGgQ==", "location"=>{"address"=>"Ataköy Marina, 34140, Bakırköy, İstanbul, Türkiye"}, "lng"=>"28.87443200000007", "lat"=>"40.971388", "formatted_address"=>"Ataköy Marina, 34140 Bakırköy/İstanbul, Türkiye", "commit"=>"Finish", "boat_id"=>"241", "id"=>"location"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Boat Load (0.2ms) SELECT "boats".* FROM "boats" WHERE "boats"."user_id" = ? AND "boats"."id" = ? LIMIT 1 [["user_id", 1], ["id", 241]]
Completed 400 Bad Request in 51ms
ActionController::ParameterMissing (param is missing or the value is empty: boat):
app/controllers/boat_steps_controller.rb:50:in `boat_params'
app/controllers/boat_steps_controller.rb:25:in `update'
And when I erase #boat.update(boat_params) from #update action (which is wrong) but then I receive an error,
NoMethodError (undefined method `update' for nil:NilClass):
app/controllers/boat_steps_controller.rb:32:in `update'
I just put an easy else condition as;
def update
#boat = current_user.boats.find(params[:boat_id])
case step
when :picture
#picture.update(picture_params)
when :location
#location = #boat.build_location
#location.update_attributes(address: params[:location][:address], longitude: params[:lng], latitude: params[:lat])
else
#boat.update(boat_params)
end
render_wizard #boat
end

Resources