Getting error (undefined method) for form_with - html

I have _form.html.erb. and on the first line of code, it is throwing this error:
undefined method `assessments_path' for #ActionView::Base:0x00000000229750
Did you mean? asset_path
couple of points:
in routes 'poweruser' is a namespace
in models assessment.rb is
not folder poweruser (as I plan to use it for other pages that anyone can access not just powerusers).
Any ideas what I am missing?
Here is the code:
<%= form_with(model: [#assessment], local: true) do |form| %>
<%= render "shared/error_messages", resource: form.object %>
<div class="form-group">
<%= form.label :name %>
<%= form.text_field :name, class: "form-control" %>
</div>
<% end %>
Here is the controller
module Powerusers
class AssessmentsController < ApplicationController
before_action :authenticate_user!
# before_action :set_assessment
# before_action :set_assessment, only: [:set_assessment, :show, :edit, :update, :destroy]
# Overwrite any of the RESTful controller actions to implement custom behavior
# For example, you may want to send an email after a foo is updated.
#
# def update
# super
# send_foo_updated_email(requested_resource)
# end
def index
#pagy, #assessments = pagy(Assessment.sort_by_params(params[:sort], sort_direction))
# We explicitly load the records to avoid triggering multiple DB calls in the views when checking if records exist and iterating over them.
# Calling #assessments.any? in the view will use the loaded records to check existence instead of making an extra DB call.
#assessments.load
end
# GET /assessments/new
def new
#assessment = Assessment.new
#assessment.assessment_sections.new
end
here is the assessment.rb (not it is not in a sub-folder poweruser)
class Assessment < ApplicationRecord
belongs_to :company
has_many :assessment_sections, inverse_of: :assessment
has_many :questions, through: :assessment_sections
accepts_nested_attributes_for :assessment_sections, reject_if: :all_blank,
allow_destroy: true
accepts_nested_attributes_for :questions, reject_if: :all_blank,
allow_destroy: true
end
Here is the routes
# PowerUser
authenticated :user, lambda { |u| u.admin? } do
namespace :powerusers do
resources :assessments do
resources :assessment_sections do
resources :questions
end
end
end
end

As you have namespace in routes, you need to specify that with form_with
<%= form_with(model: [:powerusers, #assessment], local: true) do |form| %>

Related

How to place a form to create a new entry on the main page. RoR

I install Ubuntu, RoR and all RoR components. Then I update question.
I need to get the form as in this screenshot. I need this part. So that it appears after clicking the Add button. I understand the logic of adding a form after clicking a button, but I can’t understand how the code of the form itself should look. Even a form with only text_field launches a site with an error 500. I may not know a lot, I'm just learning RoR.
index.html.erb
<style type="text/css">
p{
font-family: Times New Roman
}
</style>
<p>
<strong><h1><%= #title %></h1>
<br><br><br>
<% #projects.each do |project| %>
<h2 style="text-transform: uppercase"><%= project.title %></h2>
<ul>
<% #todos.each do |todo| %>
<% if todo.project_id == project.id %>
<li><%= todo.text %></li>
<% end %>
<% end %>
</ul>
<% end %>
<h2>Новая задача</h2>
<%= form_with(model: #todo, local: true) do |todo| %>
<%= todo.text_field :text %>
<%= todo.select (:project_id, option_for_select(project_array)) %>
<%= todo.submit "Отмена"%>
<%= todo.submit "ОК" %>
<% end %>
</strong>
</p>
projects_controller.rb
class ProjectsController < ApplicationController
before_action :set_project, only: [:show, :edit, :update, :destroy]
# GET /projects
# GET /projects.json
def index
#projects = Project.all
end
# GET /projects/1
# GET /projects/1.json
def show
end
# GET /projects/new
def new
#project = Project.new
end
# GET /projects/1/edit
def edit
end
# POST /projects
# POST /projects.json
def create
#project = Project.new(project_params)
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: 'Project was successfully created.' }
format.json { render :show, status: :created, location: #project }
else
format.html { render :new }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /projects/1
# PATCH/PUT /projects/1.json
def update
respond_to do |format|
if #project.update(project_params)
format.html { redirect_to #project, notice: 'Project was successfully updated.' }
format.json { render :show, status: :ok, location: #project }
else
format.html { render :edit }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
# DELETE /projects/1
# DELETE /projects/1.json
def destroy
#project.destroy
respond_to do |format|
format.html { redirect_to projects_url, notice: 'Project was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_project
#project = Project.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def project_params
params.require(:project).permit(:title)
end
end
todos_controller.rb
class TodosController < ApplicationController
before_action :set_todo, only: [:show, :edit, :update, :destroy]
# GET /todos
# GET /todos.json
def index
#todos = Todo.all
end
# GET /todos/1
# GET /todos/1.json
def show
end
# GET /todos/new
def new
#todo = Todo.new
end
# GET /todos/1/edit
def edit
end
# POST /todos
# POST /todos.json
def create
#todo = Todo.new(todo_params)
respond_to do |format|
if #todo.save
format.html { redirect_to #todo, notice: 'Todo was successfully created.' }
format.json { render :show, status: :created, location: #todo }
else
format.html { render :new }
format.json { render json: #todo.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /todos/1
# PATCH/PUT /todos/1.json
def update
respond_to do |format|
if #todo.update(todo_params)
format.html { redirect_to #todo, notice: 'Todo was successfully updated.' }
format.json { render :show, status: :ok, location: #todo }
else
format.html { render :edit }
format.json { render json: #todo.errors, status: :unprocessable_entity }
end
end
end
# DELETE /todos/1
# DELETE /todos/1.json
def destroy
#todo.destroy
respond_to do |format|
format.html { redirect_to todos_url, notice: 'Todo was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_todo
#todo = Todo.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def todo_params
params.require(:todo).permit(:text, :isCompleted, :project_id)
end
end
todoshnik_controller.rb
class TodoshnikController < ApplicationController
def index
#title = 'Задачи'
#projects = Project.all
#todos = Todo.all
#todo = Todo.new
#project_array = #projects.map { |project| [project.title, project.id] }
end
def create
end
def update
end
end
routes.rb
Rails.application.routes.draw do
root 'todoshnik#index'
resources :todos
resources :projects
end
Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.6.5'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.0'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 3.11'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use Active Storage variant
# gem 'image_processing', '~> 1.2'
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end
group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'web-console', '>= 3.3.0'
end
group :test do
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
# Easy installation and use of web drivers to run system tests with browsers
gem 'webdrivers'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
Add a #todo instance variable in the index action
def index
#title = 'Задачи'
#projects = Project.all
#todos = Todo.all
#todo = Todo.new
#project_array = #projects.map { |project| [project.title, project.id] } #minimize the use of logic in your views.
end
Add the form in your view.
<%= form_for #todo do |todo| %>
<%= todo.text_field :text %>
<%= todo.select :project_id, options_for_select(#project_array) %>
<%= todo.submit "Отмена" %>
<%= todo.submit "ОК" %>
<% end %>
If you have a TodoController with create and update action
<%= form_with(model: #todo, local: true) do |todo| %>
<%= todo.text_field :text %>
<%= todo.select :project_id, options_for_select(#project_array) %>
<%= todo.submit "ОК" %>
<% end %>
This will always point to the create action of the TodoController
The problem is #todo is not referenced in your index_controller.rb, so your index_controller.rb #index action must be:
def index
#title = 'Задачи'
#projects = Project.all
#todos = Todo.all
#todo = Todo.new
end
Then in your index.html.erb
<%= form_for #todo do |todo| %>
<%= todo.text_field :text %>
<%= project_array = #projects.map { |project| [project.title, project.id] } %>
<%= todo.select (:project_id, option_for_select(project_array)) %>
<%= todo.submit "Отмена" %>
<%= todo.submit "ОК" %>
<% end %>
try to install simple_form_for gem. It will allow you makes form without any troubles.

Rails undefined method `email' for nil:NilClass

I get the following error in Rails application. Can you help me?
I get an error when I connect two tables.
The user wants to use a table. I'm trying to manage the manager ID and user ID fields from a single table.
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
Rails 5.2.2
Database Design
Error Message
Database design and tables
schema.rb:
ActiveRecord::Schema.define(version: 2019_02_24_160401) do
create_table "projects", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
t.string "name"
t.text "description"
t.string "company"
t.bigint "manager_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["manager_id"], name: "index_projects_on_manager_id"
end
create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "username", default: "", null: false
t.string "fullname", default: ""
t.bigint "manager"
t.string "company", default: ""
t.string "department", default: ""
t.boolean "isadmin", default: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
add_foreign_key "projects", "users", column: "manager_id"
end
projects_controller.rb
class ProjectsController < ApplicationController
before_action :set_project, only: [:show, :edit, :update, :destroy]
before_action :find_users, only: [:index, :show, :new, :edit]
# GET /projects
# GET /projects.json
def index
#projects = Project.all
end
# GET /projects/1
# GET /projects/1.json
def show
end
# GET /projects/new
def new
#project = Project.new
end
# GET /projects/1/edit
def edit
end
# POST /projects
# POST /projects.json
def create
#project = Project.new(project_params)
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: 'Project was successfully created.' }
format.json { render :show, status: :created, location: #project }
else
format.html { render :new }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /projects/1
# PATCH/PUT /projects/1.json
def update
respond_to do |format|
if #project.update(project_params)
format.html { redirect_to #project, notice: 'Project was successfully updated.' }
format.json { render :show, status: :ok, location: #project }
else
format.html { render :edit }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
# DELETE /projects/1
# DELETE /projects/1.json
def destroy
#project.destroy
respond_to do |format|
format.html { redirect_to projects_url, notice: 'Project was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_project
#project = Project.find(params[:id])
end
def find_users
#users = User.all.order('created_at desc')
end
# Never trust parameters from the scary internet, only allow the white list through.
def project_params
params.require(:project).permit(:name, :description, :user_id)
end
end
Model files in model folder
project.rb and user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
has_many :projects
end
class Project < ApplicationRecord
belongs_to :user
end
calling my code email column
index.html.erb
<p id="notice"><%= notice %></p>
<h1>Projects</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Company</th>
<th>Manager</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #projects.each do |project| %>
<tr>
<td><%= project.name %></td>
<td><%= project.description %></td>
<td><%= project.company %></td>
<td><%= project.user.email %></td>
<td><%= link_to 'Show', project %></td>
<td><%= link_to 'Edit', edit_project_path(project) %></td>
<td><%= link_to 'Destroy', project, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Project', new_project_path %>
Your Project has a manager_id, but no table called managers, instead it's users. So in your relationship between projects and users, it needs to use the correct key.
class User < ApplicationRecord
has_many :projects, foreign_key: :manager_id
end
class Project < ApplicationRecord
belongs_to :user, foreign_key: :manager_id
end
It seems the data is not well drafted in the schema. Is User the same thing as Manager? If it is not, you should have a user_id reference in the Projects table else, you'll have to add proper associations tying manager_id to Users then you can have project.manager.email
If user is optional for Project just call project.user&.email

Nested controllers Form_with Devise Error

So, I have a RailsApp and I decided to do a nested controller to my users called backoffice.
My routes to index are working fine, but when I try to edit or create a user, I get the following error:
NoMethodError in Backoffice::Users#new
undefined method `users_path' for #<#
<Class:0x007efc6d4fd1c8>:0x007efc6cd38708>
Did you mean? user_session_path
Here are my routes:
Rails.application.routes.draw do
resources :advertises
resources :categories
devise_for :users
namespace :backoffice do
resources :users, except: [:show]
end
end
I'm using Rails 5.1.4, so the 'form_tag' and 'form_for' are replaced for the 'form_with'
Here are my _form.html.erb where are my problem:
<%= form_with(model: user, root: true) do |form| %>
The structure of the controller is
class Backoffice::UsersController < BackofficeController
before_action :set_user, only: [:show, :edit, :update, :destroy]
before_action :pundit_user
....
Could the problem be with devise? Or it's just a nested controller error?
You should probably move the devise_for call into the :backoffice namespace as that is where the users resource is located.
If you run rails routes in the command line you will see the problem. Devise is trying to call users_path but that doesn't exist, what exists is backoffice_users_path

Legacy Database CarrierWave Integration

I am having legacy database
Rails 3.2 & ruby 1.9.3p448
I wanted to develop active_admin back-end application
I wanted use CarrierWave File Uploads gem for uploading image
Following is my code in admin/item_master.rb i.e in view
form :html => { :enctype => "multipart/form-data" } do |f|
f.inputs "Item Details" do
f.input :IMTNAME
f.input :IMTBRIEFDESC
f.input :IMTDETAILDESC
f.input :IMTIMAGE, :as => :file
end
f.actions
end
Following is my code in model
class ItemMaster < ActiveRecord::Base
set_table_name "MDIMT"
attr_accessible :IMTNAME, :IMTBRIEFDESC, :IMTDETAILDESC, :IMTIMAGE
mount_uploader :IMTIMAGE, ImtimageUploader
end
It givesme Following Error
NameError in Admin::ItemMastersController#update
uninitialized constant IMTIMAGE

mysql keeps pulling select email NULL for session in RoR

I tried using Devise but since that didn't work out for me, I decided to build the authentication and sessions from scratch. I realize the problem wasn't devise, but it's mysql. For some reason, when I register a user, the information and attributes are stored in the database. When I login using the email and password, it keeps telling me that it's an invalid email/password. The log looks like this:
Processing by SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"NFudGruZS79uwDrKzbHDQrBjlcwQ7AkC958vI4aHDAs=", "session"=>{"email"=>"first#abc.com", "password"=>"[FILTERED]"}, "commit"=>"Sign in"}
User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`email` IS NULL LIMIT 1
After some investigation, I know it's not because I didn't install mysql or other gems properly because a brand new app works just fine.
Does anyone know why it's not pulling the email I entered and pulling email is NULL instead?
Should I just create a new database and switch my database.yml file to the new database instead?
Thanks in advance.
EDIT - SOME MORE CODE
user model:
class User < ActiveRecord::Base
attr_accessor :password
attr_accessible :name, :email, :secondary_email, :password, :password_confirmation, :gender
has_many :user_owner_relationships
has_many :owners, :through => :user_owner_relationships
has_many :cash_endowments
has_many :checks, :through => :cash_endowments
has_many :owners, :through => :cash_endowments
email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, :presence => true,
:uniqueness => { :case_sensitive => false },
:format => { :with => email_regex }
validates :name, :presence => true,
:length => { :maximum => 40 }
validates :password, :presence => true,
:confirmation => true,
:length => { :within => 6..20 }
sessions_controller (user controller is standard)
def new
#title = "Sign in"
end
def create
user = User.authenticate(params[:email], params[:password])
if user
session[:user_id] = user.id
redirect_to root_path, :notice => "Welcome '#{user.first_name}"
else
flash.now.alert = "Invalid email or password."
render "new"
end
end
Rookie mistake -
It's actually because my new.html.erb for the sessions controller was not pulling the :session symbol from this code:
<%= form_for (:session, :url => sessions_path) do |f| %>
So I just ended up using form_tag instead.