Đỗ Tiến Đỗ Tiến - 5 months ago 16
Ruby Question

Params value couldn't be saved after creating form

currently I can submit and create my form. However, the problem is there is one field in my table that has a nill value, which is the created_by column. I don't know where its value is passed to since it doesn't throw me any error. I guess, somehow, my create method couldn't pass the value of current_user.id into the field created_by in the commodity group table, and I think I have set up correctly the relationship between user and commodity group.
Basically, all I want is if a user creates a commodity group, his id will be saved into the column created_by in the table commodity group, and if he updates the info on a commodity group, his id will be saved into the column update_by so that I can retrieve his name or email into the view by doing something like this:

<p>
Created by: <%= @commodity_group.user.name %>
Updated by: <%= @commodity_group.user.name %>
</p>


Update: I don't know somehow the current_user.id can be saved into the column created_by now. However, when I call <%= @commodity_group.user.name %>, I get this error:


undefined method `name' for nil:NilClass


Here are all the files:

user.rb:

class User < ActiveRecord::Base
extend FriendlyId
include Filterable

friendly_id :slug_candidates, use: :history
has_secure_password
acts_as_paranoid

has_many :activities
has_many :pricing_histories

has_many :commodity_groups_created, class_name: 'CommodityGroup',
foreign_key: :created_by
has_many :commodity_groups_updated, class_name: 'CommodityGroup',
foreign_key: :updated_by
end


commodity_group.rb:

class CommodityGroup < ActiveRecord::Base
extend FriendlyId
friendly_id :code, use: :history

belongs_to :created_user,
class_name: 'User',
primary_key: :id,
foreign_key: :created_by
belongs_to :updated_user,
class_name: 'User',
primary_key: :id,
foreign_key: :updated_by

validates_presence_of :code
validates_presence_of :name
# validates_presence_of :user
end


commodity_groups/_form.html.haml:

%div.page-content-wrapper
%div.page-content
= render 'header'
%div.row
.col-md-12
.portlet.light.form-fit
.portlet-title
- if defined? title
.caption
%i.icon-user.font-blue-hoki
%span.caption-subject.font-blue-hoki.bold.uppercase
= title
.portlet-body.form
= form_for @commodity_group, html: {class: 'form-horizontal form-bordered form-label-stripped'} do |f|
.form-body
.form-group
%label.control-label.col-md-3 Code
.col-md-9
= f.text_field :code, placeholder: 'Code', class: 'form-control'
.form-group.last
%label.control-label.col-md-3 Name
.col-md-9
= f.text_field :name, placeholder: 'Name', class: 'form-control'
.form-actions
.row
.col-md-offset-3.col-md-9
%button.btn.green{:type => 'submit'}
%i.fa.fa-check
Submit
= link_to "Cancel", locations_path, class: 'btn default'


commodity_groups_controller.rb:

class CommodityGroupsController < ApplicationController
before_action :set_commodity_group, only: [:show, :edit, :update, :destroy]

# GET /commodity_groups
def index
@commodity_groups = CommodityGroup.all
end

# GET /commodity_groups/1
def show
end

# GET /commodity_groups/new
def new
@commodity_group = current_user.commodity_groups_created.build
end

# GET /commodity_groups/1/edit
def edit
end

# POST /commodity_groups
def create
@commodity_group = current_user.commodity_groups_created.create(commodity_group_params)

if @commodity_group.save!
redirect_to commodity_groups_path, notice: init_message(:success, t('message.new_success', page_name: t('page_name.commodity_group')))
else
redirect_to new_commodity_group_path, notice: init_message(:error, t('message.new_error', page_name: t('page_name.commodity_group')))
end
end

# PATCH/PUT /commodity_groups/1
def update
if @commodity_group.update(commodity_group_params)
@commodity_group.update_columns(created_by: current_user.id)

redirect_to @commodity_group, notice: 'Commodity group was successfully updated.'
else
render :edit
end
end

# DELETE /commodity_groups/1
def destroy
@commodity_group.destroy
redirect_to commodity_groups_url, notice: 'Commodity group was successfully destroyed.'
end

private
# Use callbacks to share common setup or constraints between actions.
def set_commodity_group
@commodity_group = CommodityGroup.find(params[:id])
end

# Only allow a trusted parameter "white list" through.
def commodity_group_params
params.require(:commodity_group).permit(:code, :name, :created_by, :updated_by, :slug)
end
end

Answer

First check if the commodity_object is saved correctly with the user id's.

If no,

Please upload the form and params that were being sent from the form.

If yes,

In the commodity_group.rb file you have given the two belongs_to relations with the same code which is wrong, so it gets confused in what relation does it take for created_by and updated_by.

Change the file as follows,

class CommodityGroup < ActiveRecord::Base
  extend FriendlyId
  friendly_id :code, use: :history

  belongs_to :created_user,
             class_name: 'User',
             primary_key: :id,
             foreign_key: :created_by
  belongs_to :updated_user,
             class_name: 'User',
             primary_key: :id,
             foreign_key: :updated_by

  validates_presence_of :code
  validates_presence_of :name
  # validates_presence_of :user
end

watch carefully the two belongs_to names. Now you can call using,

<%= @commodity_group.created_user.name %> 
<%= @commodity_group.updated_user.name %> 

The created_user and updated_user will be taken based on the assosciations.