How to update created_by field in scaffolding generated code? - ruby-on-rails

I use devise gem for authentication. I generated a scaffold for model M. I would like to update the created_by field with the user id from the login page. How do I achieve this?
I have 2 fields in the model F1 and F2.
The form that scaffold creates shows input for users to enter values for F1 and F2. How do I update the value for created_by field using the current_user from devise? Because the create action seems to be entering only the fields from the form.
<%= form_with(model: M, local: true) do |form| %>
<% if M.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(M.errors.count, "error") %> prohibited this movie from being saved:</h2>
<ul>
<% M.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :F1 %>
<%= form.text_field :F1 %>
</div>
<div class="field">
<%= form.label :F2 %>
<%= form.text_field :F2 %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
How to I update the model with current_user value in the above form without exposing that field to the user?
This is my controller:
class MsController < ApplicationController
before_action :set_M, only: [:show, :edit, :update, :destroy]
# GET /Ms
# GET /Ms.json
def index
#Ms = M.all
#categories = #Ms.uniq.pluck(:category)
#Ms_by_category = Hash.new
#categories.each do |category|
#Ms_by_category[category] = M.where(:category => category)
end
end
# GET /Ms/1
# GET /Ms/1.json
def show
end
# GET /Ms/new
def new
#M = M.new
end
# GET /Ms/1/edit
def edit
end
# POST /Ms
# POST /Ms.json
def create
#M = M.new(M_params)
respond_to do |format|
if #M.save
format.html { redirect_to #M, notice: 'M was successfully created.' }
format.json { render :show, status: :created, location: #M }
else
format.html { render :new }
format.json { render json: #M.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /Ms/1
# PATCH/PUT /Ms/1.json
def update
respond_to do |format|
if #M.update(M_params)
format.html { redirect_to #M, notice: 'M was successfully updated.' }
format.json { render :show, status: :ok, location: #M }
else
format.html { render :edit }
format.json { render json: #M.errors, status: :unprocessable_entity }
end
end
end
# DELETE /Ms/1
# DELETE /Ms/1.json
def destroy
#M.destroy
respond_to do |format|
format.html { redirect_to Ms_url, notice: 'M was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_M
#M = M.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def M_params
params.require(:M).permit(:title, :category, :rating)
end
end

So simple in creating action change your method, for example, you just need to create the client
before_action :authenticate_user!
def create
#client = Client.new(name: params[:name], address: params[:address],created_by: current_user.email )
if #client.save
redirect_to #client
else
render 'new'
end
end
There should be a field like created_by exist in the table.

You need to add users reference to M model and add associations. created_by is not the best name for it. Let imagine that M is abbreviation for Music. In this case you need to create a migration
add_reference :musics, :user
Add to the Music model
belongs_to :user
And to the User model
has_many :musics
And change in the controller
def new
#music = current_user.musics.new
end
def create
#music = current_user.musics.new(M_params)
respond_to do |format|
if #music.save
format.html { redirect_to #music, notice: 'Music was successfully created.' }
format.json { render :show, status: :created, location: #music }
else
format.html { render :new }
format.json { render json: #music.errors, status: :unprocessable_entity }
end
end
end

Related

can't save to database with hidden field

I have 2 models, one of patients and another of indicadions, I think I have the relationships between the models correctly placed, what I cannot make it work is that the patient_id is placed in the hidden field
my models:
patient: has_many :prescription, dependent: :destroy
indication: belongs_to :patient
my view:
<%= form_with(model: prescription) do |form| %>
<% if prescription.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(prescription.errors.count, "error") %> prohibited this prescription from being saved:</h2>
<ul>
<% prescription.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= form.hidden_field :patient_id, value: "patient_id" %>
<div class="form-group">
<%= form.label :content %>
<%= form.text_area :content, class:'form-control' %>
</div>
<%= form.submit "SAVE",class:'btn save' %>
<% end %>
The controller:
class PrescriptionsController < ApplicationController
before_action :set_prescription, only: %i[ show edit update destroy ]
# GET /prescriptions or /prescriptions.json
def index
#prescriptions = Prescription.all
end
# GET /prescriptions/1 or /prescriptions/1.json
def show
end
# GET /prescriptions/new
def new
#prescription = Prescription.new
end
# GET /prescriptions/1/edit
def edit
end
# POST /prescriptions or /prescriptions.json
def create
#prescription = Prescription.new(prescription_params)
respond_to do |format|
if #prescription.save
format.html { redirect_to #prescription, notice: "La receta se creó con éxito." }
format.json { render :show, status: :created, location: #prescription }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #prescription.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /prescriptions/1 or /prescriptions/1.json
def update
respond_to do |format|
if #prescription.update(prescription_params)
format.html { redirect_to #prescription, notice: "Prescription was successfully updated." }
format.json { render :show, status: :ok, location: #prescription }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #prescription.errors, status: :unprocessable_entity }
end
end
end
# DELETE /prescriptions/1 or /prescriptions/1.json
def destroy
#prescription.destroy
respond_to do |format|
format.html { redirect_to prescriptions_url, notice: "Prescription was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_prescription
#prescription = Prescription.find(params[:id])
end
# Only allow a list of trusted parameters through.
def prescription_params
params.require(:prescription).permit(:content, :patient_id)
end
end
Instead of using a hidden input you might actually want to nest the routes to makes the relationship explicit instead of implicit:
resources :patients do
resources :perscriptions, shallow: true
end
class PrescriptionsController < ApplicationController
before_action :set_patient
before_action :set_prescription, only: %i[ show edit update destroy ]
# GET /patients/1/prescriptions or /patients/1/prescriptions.json
def index
#prescriptions = #patient.perscriptions
end
# GET /prescriptions/1 or /prescriptions/1.json
def show
end
# GET /patients/1/prescriptions/new
def new
#prescription = Prescription.new
end
# GET /prescriptions/1/edit
def edit
end
# POST /patients/1/prescriptions or /patients/1/prescriptions.json
def create
#prescription = #patient.perscriptions.new(prescription_params)
respond_to do |format|
if #prescription.save
format.html { redirect_to #prescription, notice: "La receta se creó con éxito." }
format.json { render :show, status: :created, location: #prescription }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #prescription.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /prescriptions/1 or /prescriptions/1.json
def update
respond_to do |format|
if #prescription.update(prescription_params)
format.html { redirect_to #prescription, notice: "Prescription was successfully updated." }
format.json { render :show, status: :ok, location: #prescription }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #prescription.errors, status: :unprocessable_entity }
end
end
end
# DELETE /prescriptions/1 or /prescriptions/1.json
def destroy
#prescription.destroy
respond_to do |format|
format.html { redirect_to prescriptions_url, notice: "Prescription was successfully destroyed." }
format.json { head :no_content }
end
end
private
def set_patient
#patient = Patient.find(params[:patient_id])
end
def set_prescription
#prescription = Prescription.find(params[:id])
end
# Only allow a list of trusted parameters through.
def prescription_params
params.require(:prescription).permit(:content)
end
end
<%= form_with(model: [#patient, #perscription]) do |form| %>
<% if prescription.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(prescription.errors.count, "error") %> prohibited this prescription from being saved:</h2>
<ul>
<% prescription.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= form.label :content %>
<%= form.text_area :content, class:'form-control' %>
</div>
<%= form.submit "SAVE", class:'btn save' %>
<% end %>

Rails model form f.select do not assign selected value to model key

sorry for this question but I'm struggling with this issue for hours now and can't find the answer anywhere.
Here is the thing, I have a rails app with "Reservation" and "Space" models with the following relations:
class Reservation < ActiveRecord::Base
belongs_to :space
belongs_to :user
end
class Space < ActiveRecord::Base
belongs_to :condo
has_many :reservations
end
When the user creates a new Reservation, in the form he gets to choose from a dropdown (f.select) the spaces available for him. The f.select in the form look like this:
<div class="field">
<%= #user_spaces = current_user.condo.spaces
f.select :space_id,
options_from_collection_for_select(#user_spaces, :id, :name), :prompt => "Select space"
%>
</div>
That select it supose to assign a value to the key "space_id" in the Reservation that is being created (column's table is created). But when I check the last reservation in Rails console, space_id value is "nil". What am I doing wrong?
Thank you very much for your help
Reservation controller file:
class ReservationsController < ApplicationController
before_action :set_reservation, only: [:show, :edit, :update, :destroy]
# GET /reservations
# GET /reservations.json
def index
#reservations = Reservation.all
end
# GET /reservations/1
# GET /reservations/1.json
def show
end
# GET /reservations/new
def new
#reservation = Reservation.new
end
# GET /reservations/1/edit
def edit
end
# POST /reservations
# POST /reservations.json
def create
#reservation = Reservation.new(reservation_params)
#user = current_user.id
#reservation.user_id = #user
respond_to do |format|
if #reservation.save
format.html { redirect_to #reservation, notice: 'Reservation was successfully created.' }
format.json { render :show, status: :created, location: #reservation }
else
format.html { render :new }
format.json { render json: #reservation.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /reservations/1
# PATCH/PUT /reservations/1.json
def update
respond_to do |format|
if #reservation.update(reservation_params)
format.html { redirect_to #reservation, notice: 'Reservation was successfully updated.' }
format.json { render :show, status: :ok, location: #reservation }
else
format.html { render :edit }
format.json { render json: #reservation.errors, status: :unprocessable_entity }
end
end
end
# DELETE /reservations/1
# DELETE /reservations/1.json
def destroy
#reservation.destroy
respond_to do |format|
format.html { redirect_to reservations_url, notice: 'Reservation was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_reservation
#reservation = Reservation.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def reservation_params
params.require(:reservation).permit(:eventdate)
end
end
Space controller file:
class SpacesController < ApplicationController
before_action :set_space, only: [:show, :edit, :update, :destroy]
# GET /spaces
# GET /spaces.json
def index
#spaces = Space.all
end
# GET /spaces/1
# GET /spaces/1.json
def show
end
# GET /spaces/new
def new
#space = Space.new
end
# GET /spaces/1/edit
def edit
end
# POST /spaces
# POST /spaces.json
def create
#space = Space.new(space_params)
respond_to do |format|
if #space.save
format.html { redirect_to #space, notice: 'Space was successfully created.' }
format.json { render :show, status: :created, location: #space }
else
format.html { render :new }
format.json { render json: #space.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /spaces/1
# PATCH/PUT /spaces/1.json
def update
respond_to do |format|
if #space.update(space_params)
format.html { redirect_to #space, notice: 'Space was successfully updated.' }
format.json { render :show, status: :ok, location: #space }
else
format.html { render :edit }
format.json { render json: #space.errors, status: :unprocessable_entity }
end
end
end
# DELETE /spaces/1
# DELETE /spaces/1.json
def destroy
#space.destroy
respond_to do |format|
format.html { redirect_to spaces_url, notice: 'Space was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_space
#space = Space.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def space_params
params.require(:space).permit(:name)
end
end
And full Reservation Form:
<%= form_for(#reservation) do |f| %>
<% if #reservation.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#reservation.errors.count, "error") %> prohibited this reservation from being saved:</h2>
<ul>
<% #reservation.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :eventdate %><br>
<%= f.date_select :eventdate %>
</div>
<div class="field">
<%= #user = current_user.condo.spaces
f.select :space_id,
options_from_collection_for_select(#user, :id, :name), :prompt => "Select space"
%>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
pretty sure you need to permit the space_id attribute in your strong params.
def reservation_params
params.require(:reservation).permit(:eventdate, :space_id)
end
whats happening is that when you go to create a reservation, youre passing in set of params, that is the output of reservation_params
#reservation = Reservation.new(reservation_params)
if space_id is not being permitted in your strong params, then it will be nil when created.
if this is not the issue, can you post what params are getting to the server, and what the output of reservation_params are.

Param is missing or the value is empty: ParameterMissing in ResultsController#update

I have a Result that belongs to a Website. After I create the website I also create the result and redirect to its edit page. Here I want to add some more values.
My problem is: When I try to update my Result, then I get:
param is missing or the value is empty: result
Request
Parameters:
{"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"GRN/y/04Qbsm9DzlUAbUYF8ZSv2EMHnRZgBZY/6GMDlOBdq8V5Uncij9VRp51uydC6M/qc61jPWwpUehSuc5xA==", "data"=>["//html/body/div[position() = 3]/ul/li[position() = 16]/ul/li[position() = 2]/child::text()", "//html/body/div[position()
= 3]/ul/li[position() = 16]/ul/li[position() = 2]/p/a/child::text()", "//html/body/div[position() = 3]/ul/li[position() = 16]/ul/li[position() = 4]/child::text()", "//html/body/div[position()
= 3]/ul/li[position() = 16]/ul/li[position() = 5]/a/child::text()"], "commit"=>"Update Result", "id"=>"66"}
This is how my Result params looks like
def result_params
params.require(:result).permit(:data)
end
My model:
class Result < ActiveRecord::Base
belongs_to :website
attr_accessor :website_id
attr_accessor :data
serialize :data, Array
end
Here is my controller code:
class ResultsController < ApplicationController
before_action :set_result, only: [:show, :edit, :update, :destroy]
# GET /Results
# GET /Results.json
def index
#results = Result.all
end
# GET /Results/1
# GET /Results/1.json
def show
end
# GET /Results/new
def new
#result = Result.new
end
# GET /Results/1/edit
def edit
#result = Result.find(params[:id])
end
# POST /Results
# POST /Results.json
def create
#result = Result.new(result_params)
respond_to do |format|
if #result.save
format.html { redirect_to #result, notice: 'Result was successfully created.' }
format.json { render :show, status: :created, location: result }
else
format.html { render :new }
format.json { render json: #result.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /Results/1
# PATCH/PUT /Results/1.json
def update
respond_to do |format|
if #result.update(result_params )
format.html { redirect_to #result, notice: 'Result was successfully updated.' }
format.json { render :show, status: :ok, location: #result }
else
format.html { render :edit }
format.json { render json: #result.errors, status: :unprocessable_entity }
end
end
end
# DELETE /Results/1
# DELETE /Results/1.json
def destroy
#result.destroy
respond_to do |format|
format.html { redirect_to results_url, notice: 'Result was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_result
#result = Result.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def result_params
params.permit(:data => [])
end
end
My view:
<%= form_for(#result) do |f| %>
<% if #result.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#result.errors.count, "error") %> prohibited this result from being saved:</h2>
<ul>
<% #result.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<% if #result.website.url != nil %>
<%= atts = get_all_elements(#result.website.url)%>
<% atts.each do |p| %>
<div>
<%= check_box_tag "data[]", get_xpath_from_node(p)%>
<%= p.text %>
</div>
<%end%>
<% end%>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And this is the place where i call the edit result page:
def update
respond_to do |format|
if #website.update(website_params)
format.html { redirect_to #website, notice: 'Website was successfully updated.' }
format.json { render :show, status: :ok, location: #website }
else
format.html { render :edit }
format.json { render json: #website.errors, status: :unprocessable_entity }
end
end
end
Ive allready tryed every solution I could find, but none of them seemed to work for me.
The problem lies here:
params.require(:result).permit(:data)
From require documentation,
require ensures that a parameter is present. If it's present, returns
the parameter at the given key, otherwise raises an
ActionController::ParameterMissing error.
You are requiring result parameter but it's missing from the params. All your values are inside data param. Removing require should do the trick.
params.permit(:data)
If you want to keep require, wrap data inside result in forms.
I know, what you met. if you strong params is
def result_params
params.require(:result).permit(:data)
end
Your parameters should has the format like this
Parameters: {"result"=>{"data"=>"string"}}
and your parameters is just
Parameters: {"data"=>"string"}
so you should remove the "result"

Rails How to pass params in cross model system

I am unable to figure out the method to pass params to a link tag. What I want to do is When someone clicks on the Join Group link, the Membership model shall have a new row with group_id as the current group id and the user id as the current user id. The Membership model currently consists of two columns : user_id and group_id that maps users to groups. Can anyone help me with the mistake I am making.
Here is the code
Groups : show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Title:</strong>
<%= #group.title %>
</p>
<p>
<strong>Desc:</strong>
<%= #group.desc %>
</p>
<p>
<strong>Creator:</strong>
<%= #creator.first_name %>
</p>
<%= link_to 'Join Group', memberships_path(:group_id => #group.id, :user_id => current_user.id ), method: :post %>
<%= link_to 'Edit', edit_group_path(#group) %> |
<%= link_to 'Back', groups_path %>
and here is the Memberships controller
class MembershipsController < ApplicationController
before_action :set_membership, only: [:show, :edit, :update, :destroy]
# GET /memberships
# GET /memberships.json
def index
#memberships = Membership.all
end
# GET /memberships/1
# GET /memberships/1.json
def show
#membership = Membership.find(params[:id])
#user = User.find(#membership.user_id)
#group = Group.find(#membership.group_id)
end
# GET /memberships/new
def new
#membership = Membership.new
end
# GET /memberships/1/edit
def edit
end
# POST /memberships
# POST /memberships.json
def create
#membership = Membership.new(membership_params)
respond_to do |format|
if #membership.save
format.html { redirect_to #membership, notice: 'Membership was successfully created.' }
format.json { render :show, status: :created, location: #membership }
else
format.html { render :new }
format.json { render json: #membership.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /memberships/1
# PATCH/PUT /memberships/1.json
def update
respond_to do |format|
if #membership.update(membership_params)
format.html { redirect_to #membership, notice: 'Membership was successfully updated.' }
format.json { render :show, status: :ok, location: #membership }
else
format.html { render :edit }
format.json { render json: #membership.errors, status: :unprocessable_entity }
end
end
end
# DELETE /memberships/1
# DELETE /memberships/1.json
def destroy
#membership.destroy
respond_to do |format|
format.html { redirect_to memberships_url, notice: 'Membership was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_membership
#membership = Membership.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def membership_params
params.require(:membership).permit(:user_id, :group_id)
end
end
You should have a method in your controller that handles adding a user to a group, something like:
class MembershipsController < ApplicationController
...
def join_group
#user = User.find(params[:user]
#user.group_id = params[:group_id].to_i
end
...
end
Then routes.rb needs a path to that controller method:
get 'memberships/join_group' => 'memberships#join_group'
which will result in a path like memberships_join_group_path that you will use in your link_to:
<%= link_to 'Join Group', memberships_join_group_path(:group_id => #group.id, :user_id => current_user.id ) %>
The path you're currently using is sending params to your index method.
try
def create
#member = current_user.members.build(:group_id => params[:group_id])
if #member.save
flash[:notice] = "You have joined this group."
redirect_to members_path
else
flash[:error] = "Unable to join."
redirect_to members_path
end
end
and use memberships instead of members

Getting a "NoMethodError in Boards#show" error when going to #new action (not trying to access a method, and the variable exists)

I'm very new to Ruby on Rails, so forgive if this is a stupid mistake.
I used a rails generate scaffold command to generate a "board" scaffold with a title:string and message:text. Now, I'm trying to go to localhost:3000/boards/new and I'm getting a "NoMethodError in Boards#show" error when I try to access board.message. I don't get any error when I try to access board.title.
Code:
form.html.erb
<%= form_for(#board) do |f| %>
<% if #board.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#board.errors.count, "error") %> prohibited this board from being saved:</h2>
<ul>
<% #board.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :message %><br />
<%= f.text_area :message %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I'm specifically getting the error on line 20 (<%= f.text_area :message %>)
board.rb
class Board < ActiveRecord::Base
attr_accessible :message, :title
has_many :posts
end
*boards_controller.rb*
class BoardsController < ApplicationController
# GET /boards
# GET /boards.json
def index
#boards = Board.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #boards }
end
end
# GET /boards/1
# GET /boards/1.json
def show
#board = Board.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #board }
end
end
# GET /boards/new
# GET /boards/new.json
def new
#board = Board.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #board }
end
end
# GET /boards/1/edit
def edit
#board = Board.find(params[:id])
end
# POST /boards
# POST /boards.json
def create
#board = Board.new(params[:board])
respond_to do |format|
if #board.save
format.html { redirect_to #board, notice: 'Board was successfully created.' }
format.json { render json: #board, status: :created, location: #board }
else
format.html { render action: "new" }
format.json { render json: #board.errors, status: :unprocessable_entity }
end
end
end
# PUT /boards/1
# PUT /boards/1.json
def update
#board = Board.find(params[:id])
respond_to do |format|
if #board.update_attributes(params[:board])
format.html { redirect_to #board, notice: 'Board was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #board.errors, status: :unprocessable_entity }
end
end
end
# DELETE /boards/1
# DELETE /boards/1.json
def destroy
#board = Board.find(params[:id])
#board.destroy
respond_to do |format|
format.html { redirect_to boards_url }
format.json { head :no_content }
end
end
end
routes.rb
Anonymous::Application.routes.draw do
resources :boards
resources :posts
root :to => "boards#index"
end
Can anyone please explain this to me?

Resources