rails won't save form field - ruby-on-rails

I have a formfield in my form like this:
<div class="tags">
<%= f.label :tags %>
<%= f.text_area :tags %>
</div>
I ran a migration like this:
class AddTagsToIssues < ActiveRecord::Migration
def change
add_column :issues, :tags, :text
end
end
When i save, the new row is added to db, but tags = nil, although I typed something like 'test' in de text_area
in my development log I have:
Unpermitted parameters: tags
I have tried whitelisting in my controller:
def create
#issue = Issue.new(issue_params)
Issue.new(params.permit(:tags))
but this doesn't work.
Update for follow up question:
Full create method:
def create
def issue_params
params.require(:issue).permit(:tags)
end
#issue = Issue.new(issue_params)
Issue.new(params.permit(:tags))
respond_to do |format|
if #issue.save
format.html { redirect_to #issue, notice: 'Issue was successfully created.' }
format.json { render action: 'show', status: :created, location: #issue }
else
format.html { render action: 'new' }
format.json { render json: #issue.errors, status: :unprocessable_entity }
end
end
end
The model:
class Issue < ActiveRecord::Base
belongs_to :project
end
The table create query:
class CreateIssues < ActiveRecord::Migration
def change
create_table :issues do |t|
t.string :title
t.text :description
t.integer :no_followers
t.timestamps
end
end
end
So with this I don't have permission problems, that only happened with the later adding of the tags, and then only with the tags.

tags is being set as nil because you have not permitted it.
Permit tags in the issue_params method as below:
def issue_params
params.require(:issue).permit(:tags,...)
end
where, ... refers to other fields in model Issue.
Your create action should look something like this,
def create
#issue = Issue.new(issue_params) ## issue_params called
if #issue.save ## save the record
redirect_to #issue, notice: 'Issue was successfully created.'
else
render action: 'new'
end
end

Related

Creating items with scaffolding not showing attributes after creation - Rails/Devise

I'm relatively new to Rails. I'm trying to create an application that can allow users to create video game items and store them under their own users. I'm using the latest version of Rails and Devise.
Using scaffolding as a base, I created the Videogame model/controller within my application. After linking the video game models to the user who created them, it seems that any attributes that are entered into the creation form are not saving, or at the very least just not showing up on the videogames/index page. After trying to search around on Google and StackOverflow, I couldn't find any similar questions/guides to work with.
Any ideas on how to fix this? Any help for a Rails newbie would be greatly appreciated.
Below I've posted all files that may be relevant. Please let me know if anything else is needed. To see the whole project, see http://github.com/bmmart2/collection-manager
Image after item creation
Index page of two created items
Here is my controller:
class VideogamesController < ApplicationController
before_action :set_videogame, only: [:show, :edit, :update, :destroy]
# GET /videogames
# GET /videogames.json
def index
if user_signed_in?
#videogame = current_user.videogames.all
else
redirect_to :root
end
end
# GET /videogames/1
# GET /videogames/1.json
def show
end
# GET /videogames/new
def new
#videogame = current_user.videogames.new
end
# GET /videogames/1/edit
def edit
end
# POST /videogames
# POST /videogames.json
def create
#videogame = current_user.videogames.create(videogame_params)
respond_to do |format|
if #videogame.save
format.html { redirect_to #videogame, notice: 'Videogame was successfully created.' }
format.json { render :show, status: :created, location: #videogame }
else
format.html { render :new }
format.json { render json: #videogame.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /videogames/1
# PATCH/PUT /videogames/1.json
def update
respond_to do |format|
if #videogame.update(videogame_params)
format.html { redirect_to #videogame, notice: 'Videogame was successfully updated.' }
format.json { render :show, status: :ok, location: #videogame }
else
format.html { render :edit }
format.json { render json: #videogame.errors, status: :unprocessable_entity }
end
end
end
# DELETE /videogames/1
# DELETE /videogames/1.json
def destroy
#videogame.destroy
respond_to do |format|
format.html { redirect_to videogames_url, notice: 'Videogame was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_videogame
#videogame = Videogame.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def videogame_params
params.require(:videogame).permit(:title, :publisher, :platform, :year, :condition, :upc)
end
end
Videogame model:
class Videogame < ApplicationRecord
belongs_to :user
attr_accessor :title, :platform, :upc, :condition, :publisher, :year
end
Videogame db migration file:
class CreateVideogames < ActiveRecord::Migration[5.2]
def change
create_table :videogames do |t|
t.string :title
t.string :publisher
t.integer :condition
t.string :platform
t.string :year
t.string :upc
t.timestamps
end
add_index :videogames, :user_id
end
end
add_user_refs_to_videogame migration:
class AddUserRefsToVideogame < ActiveRecord::Migration[5.2]
def change
add_reference :videogames, :user, foreign_key: true
end
end
Edit: show view for video game
<p id="notice"><%= notice %></p>
<p>
<strong>Title:</strong>
<%= #videogame.title %>
</p>
<p>
<strong>Publisher:</strong>
<%= #videogame.publisher %>
</p>
<p>
<strong>Platform:</strong>
<%= #videogame.platform %>
</p>
<p>
<strong>Year:</strong>
<%= #videogame.year %>
</p>
<p>
<strong>Condition:</strong>
<%= #videogame.condition %>
</p>
<p>
<strong>Upc:</strong>
<%= #videogame.upc %>
</p>
<%= link_to 'Edit', edit_videogame_path(#videogame) %> |
<%= link_to 'Back', videogames_path %>
I believe the attr_accessor line in your videogame.rb file is causing the problem. Try deleting it and see if that fixes the problem.

Unpermitted parameter using fields_for Rails

I got such message in console when trying to use fields_for in Rails:
Parameters: .... "task"=>{"task_name"=>"111", "tag"=>{"tag_text"=>"222"}}, "commit"=>"Save"}
Unpermitted parameter: tag
My models with has_many and belongs_to:
class Task < ActiveRecord::Base
has_many :tags
accepts_nested_attributes_for :tags
end
class Tag < ActiveRecord::Base
belongs_to :task
end
Form helper for new/edit page:
<%= form_for(#task) do |f| %>
<%= f.text_field :task_name %>
<%= f.fields_for([#task, #task.tags.build]) do |t| %>
<%= t.text_field :tag_text %>
<% end %>
<%= f.submit 'Save' %>
<% end %>
My Task Controller (I used scaffold to generate it, and its mostly default)
class TasksController < ApplicationController
before_action :set_task, only: [:show, :edit, :update, :destroy]
def index
#tasks = Task.all
end
def show
end
def new
#task = Task.new
#task.tags.build
end
def edit
#task.tags.build
end
def create
#task = Task.new(task_params)
respond_to do |format|
if #task.save
format.html { redirect_to #task, notice: 'Task was successfully created.' }
format.json { render :edit, status: :created, location: #task }
else
format.html { render :new }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #task.update(task_params)
format.html { redirect_to edit_task_path, notice: 'Task was successfully updated.' }
format.json { render :edit, status: :ok, location: #task }
else
format.html { render :edit }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
def destroy
#task.destroy
respond_to do |format|
format.html { redirect_to tasks_url, notice: 'Task was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_task
#task = Task.find(params[:id])
end
def task_params
params.require(:task).permit(:task_name, :task_sum, :status_id, :user_id, :target_release_id, tag_attributes: [:tag_text, :task_id])
end
end
I think the problem is in the way you use fields_for. Try to make this way:
<%= f.fields_for :tags do |t| %>
That way the param tags_attributes will be send and every thing should be fine.
EDIT
Also, if you are using Rails 5, you need to set the belongs_to as optional so the accepts_nested_attributes_for can work properly. So:
class Tag < ActiveRecord::Base
belongs_to :task, optional: true
end
And the parameters sanitization in your tasks_controller.rb you do not need tag_id under tags_attributes:
def task_params:
params.require(:task).permit(:task_name, tags_attributes: [:tag_text])
end
EDIT
I think I found your problem. Try to put tags_attributes instead of tag_attributes in your task_paramsmethod.

undefined method `first_name' for nil:NilClass - No way this is Nil

User has many comments, comment belongs to many users. How do I fix this error?
undefined method `first_name' for nil:NilClass
when I try to do
<h3>Comments</h3>
<% #guide.comments.each do |comment| %>
<div>
<p><%= comment.user.first_name %></p>
</div>
<% end %>
user.rb
has_many :comments
comment.rb
class Comment < ActiveRecord::Base
belongs_to :user
end
comments migration (I added a user_id column):
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.text :body
t.integer :user_id
t.timestamps
add_foreign_key :comments, :guides
end
end
end
comments controller:
def create
#comment = Comment.new(comment_params)
respond_to do |format|
if #comment.save
format.html { redirect_to #comment, notice: 'Comment was successfully created.' }
format.json { render action: 'show', status: :created, location: #comment }
else
format.html { render action: 'new' }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
long time ago but this could be usefull for someone with the same error.
you should delegate the first_name to the user and allow nil
class Comment < ActiveRecord::Base
belongs_to :user
delegate :first_name, to: :user, allow_nil: true, prefix: true
end
then call it in you view with
<h3>Comments</h3>
<% #guide.comments.each do |comment| %>
<div>
<p><%= comment.user_first_name %></p>
</div>
<% end %>
if there is no user, then it will be display nothing and not raise an exception
Ensure that you user model has a first_name attribute. Then confirm that your comment record (s) actually have a user associated with them. You may not have the user_id column whitelisted in the Comment class, so the user is not set
class Comment
attr_accessible :user_id, ...
end
Or in rails 4 you have strong parameters instead of attr_accessible
How is attr_accessible used in Rails 4?
I'm guessing that you did not set the user id while creating the comment object. can you try the following code?
def create
#comment = current_user.comments.new(comment_params)
respond_to do |format|
if #comment.save
format.html { redirect_to #comment, notice: 'Comment was successfully created.' }
format.json { render action: 'show', status: :created, location: #comment }
else
format.html { render action: 'new' }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
Model didn't find comment.user. It may be the comment's user_id havn't been set or the user_id didn't apper in "user" table "id" column. You can print the comment id and comment.user_id and check in DB.
Do you set:
has_many :comments, :dependent => :destroy
Or it could hapeen you delete the user but the user's comments remain, then for these comments, comment.user is null.
Are you sure your user_id is set when you create a comment ?
Maybe this simple line is missing in your controller
#comment.user = current_user
In order to be sure to have a user in your comment, you should add in your Comment model
validates_presence_of :user_id
and in your User model
has_many :comments, :dependent => :destroy
Defining methods in Ruby is very simple. To solve your problem, define
class << nil
def first_name; "John" end
def last_name; "Doe" end
end
And the error will disappear. All the nil objects are now named "John Doe".

Ruby on Rails 4, Dynamically create table for each user

I'm new to Rails and I'm creating an Application where users can log in, and it dynamically generates a Table where they can make entries. I've managed to make the login but I don't realize how to create a table which is associated to a user.
My users_controller.rb class:
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
# GET /users
# GET /users.json
def index
#users = User.order(:name)
end
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to login_url, notice: "User #{#user.name} was successfully created." }
format.json { render action: 'show', status: :created, location: #user }
#HERE I WOULD LIKE TO CREATE A TABLE ASSOSSIATED TO THE USER
#rapport_table = User.rapport_table.create
else
format.html { render action: 'new' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to users_url, notice: "User #{#user.name} was successfully updated." }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(:name, :password, :password_confirmation)
end
end
rapport_table.rb
class RapportTable < ActiveRecord::Base
belongs_to :user
end
12341324123_create_rapport_tables.rb
class CreateRapportTables < ActiveRecord::Migration
def self.up
create_table :rapport_tables do |t|
t.date :date
t.text :description
t.integer :time
t.timestamps
end
end
def self.down
drop_table :rapport_tables
end
end
show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #user.name %>
</p>
<%= link_to 'Edit', edit_user_path(#user) %> |
<%= link_to 'Back', users_path %>
You never, ever want to create tables inside a database in a runtime. Instead, you'll need to create some more models:
class RaportTable < ActiveRecord::Base
belongs_to :user
has_many :columns
has_many :rows
end
class Column < ActiveRecord::Base
# attr_accessible :name, :order
belongs_to :raport_table
has_many :cells
end
class Row < ActiveRecord::Base
# attr_accessible :row_number
belongs_to :raport_table
has_many :cells
end
class Cell < ActiveRecord::Base
# attr_accessible :value
belongs_to :column
belongs_to :row
end
This should be sufficient to start with.

Unknown attribute when linking two models together

Brief overview of my app.
It's quite basic in that the User first of all creates a set A client on one page and then uses another to create and assign jobs to the user.
My Client model and view are working as expected but im unable to link my jobs model.
Here is my jobs model.
class Client < ActiveRecord::Base
has_and_belongs_to_many :jobs
end
class Job < ActiveRecord::Base
has_and_belongs_to_many :clients
end
Here is also my clients controller.
class JobsController < ApplicationController
def index
#jobs = Job.find(:all)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #job }
end
end
def new
#jobs = Job.new
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #job }
end
end
def create
#jobs = Job.new(params[:job])
respond_to do |format|
if #jobs.save
format.html { redirect_to #jobs, notice: 'Job was successfully created.' }
format.json { render json: #jobs, status: :created, location: #jobs }
else
format.html { render action: "new" }
format.json { render json: #jobs.errors, status: :unprocessable_entity }
end
end
end
def show
#jobs = Job.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #jobs }
end
end
end
In my form I have two fields. One for the job name and another which is a drop down on all the clients listed in the database.
When fill this out however and I press save im getting the following error.
ActiveRecord::UnknownAttributeError in JobsController#create
**unknown attribute: client_id**
Application Trace | Framework Trace | Full Trace
app/controllers/jobs_controller.rb:22:in `new'
app/controllers/jobs_controller.rb:22:in `create'
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"0ZVYpM9vTgY+BI55Y9yJDwCJwrwSgGL9xjHq8dz5OBE=",
"job"=>{"name"=>"Sample Monthly",
"client_id"=>"1"},
"commit"=>"Save Job"}
I have a junction table setup called clients_jobs also..
class AddClientsJobsTable < ActiveRecord::Migration
def up
create_table :clients_jobs, :id => false do |t|
t.belongs_to :job, :client
t.integer :client_id
t.integer :job_id
end
end
def down
drop_table :clients_jobs
end
end
I assume I need to declare client_id
somewhere but this is my first Rails app and im not sure where.
Any help would be greatly appreciated.
Edit: Here's my Job's form.
<%= simple_form_for :job do |f| %>
<%= f.input :name %>
<%= select("job", "client_id", Client.all.collect {|c| [ c.name, c.id ] }, {:include_blank => 'None'})%>
<%= f.button :submit %>
<% end %>
Your model states that job - client is a habtm association, but your form implements as if job belongs to (one) client. If indeed your intention is to be able to assign a job to multiple clients, your for should look something like:
<%= collection_select(:job, :client_ids, Client.all, :id, :name, {:include_blank => 'None'}, { :multiple => true }) %>
note plural 'client_ids' and allowing multiple in the input.
If a job belongs to only one user, you should not use has_and_belongs_to_many :clients.

Resources