I'm currently trying to add a collection_select of ranches to my staff
And I saw that it's better to create an extra table to make this association.
And I follow some tutorial, but is not working on my side
This is my code :
Staffs/_form :
<%= form_for(#staff) do |f| %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<%= fields_for(#staff_ranch) do |x| %>
<div class="field">
<%= x.collection_select(:ranch_id, #all_ranch, :id, :name, { }, {:multiple => true}) %>
</div>
<%end%>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
My models :
- Ranch :
has_many :ranchstaffs
has_many :staffs, :through => :ranchstaffs
- Staff :
has_many :ranchstaffs
has_many :ranches, :through => :ranchstaffs
-Ranchstaff :
belongs_to :ranch
belongs_to :staff
Staff controller :
class StaffsController < ApplicationController
before_action :set_staff, only: [:show, :edit, :update, :destroy]
# GET /ranches
# GET /ranches.json
def index
#staffs = current_user.staffs
end
# GET /ranches/1
# GET /ranches/1.json
def show
end
# GET /ranches/new
def new
#staff = Staff.new
#all_ranch = current_user.ranches
#staff_ranch = #staff.ranchstaffs.build
end
# GET /ranches/1/edit
def edit
end
# POST /ranches
# POST /ranches.json
def create
#staff = Staff.new(staff_params)
#staff.update(user_id: current_user.id)
respond_to do |format|
if #staff.save
format.html { redirect_to #staff, notice: 'Staff was successfully created.' }
format.json { render :show, status: :created, location: #staff }
else
format.html { render :new }
format.json { render json: #staff.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /ranches/1
# PATCH/PUT /ranches/1.json
def update
respond_to do |format|
if #staff.update(staff_params)
format.html { redirect_to #staff, notice: 'Staff was successfully updated.' }
format.json { render :show, status: :ok, location: #staff }
else
format.html { render :edit }
format.json { render json: #staff.errors, status: :unprocessable_entity }
end
end
end
# DELETE /ranches/1
# DELETE /ranches/1.json
def destroy
#staff.destroy
respond_to do |format|
format.html { redirect_to staffs_url, notice: 'Ranch was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_staff
#staff = Staff.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def staff_params
params.require(:staff).permit(:name, :user_id, :cat, :ranch_id)
end
end
Can you explain me why the model ranchstaff was not created after a creation of a new staff ?
As you are using fields_for you are using nested form but you are not permitting the parameters properly. First make change in your form:
<%= f.fields_for(#staff_ranch) do |x| %>
<div class="field">
<%= x.collection_select(:ranch_id, #all_ranch, :id, :name, { }, {:multiple => true}) %>
</div>
<% end %>
And then in your controller:
def staff_params
params.require(:staff).permit(:name, :user_id, :cat, ranchstaff_attributes: [ranch_id: []])
end
And in your Staff model write:
accepts_nested_attributes_for :ranchstaffs
Then your ranchstaff should be created when the User is being created.
Your ranch_id is coming in an array. So u have to specify that ranch_id would be array in strong parameters.
so your staff_params method would look like this
def staff_params
params.require(:staff).permit(:name, :user_id, :cat, :staff_ranch_attributes =>[:ranch_id => []])
end
Related
i have a rails app. i have strange problem in saving form
this is my ticket model .
class Ticket < ApplicationRecord
belongs_to :user
has_many :ticketissues , inverse_of: :ticket
accepts_nested_attributes_for :ticketissues, :reject_if => lambda { |a| a[:body].blank? }
end
this is ticketisue model
class Ticketissue < ApplicationRecord
belongs_to :user
belongs_to :ticket
validates :body, presence: true
end
this is ticket controller
class TicketsController < ApplicationController
before_action :set_ticket, only: [:show, :edit, :update, :destroy]
# GET /tickets
# GET /tickets.json
def index
#tickets = Ticket.all
end
# GET /tickets/1
# GET /tickets/1.json
def show
end
# GET /tickets/new
def new
#ticket = Ticket.new
end
# GET /tickets/1/edit
def edit
end
# POST /tickets
# POST /tickets.json
def create
#ticket = Ticket.new(ticket_params)
#ticket.user_id = current_user.id
#ticket.ticketissues.build
respond_to do |format|
if #ticket.save
format.html { redirect_to #ticket, notice: 'Ticket was successfully created.' }
format.json { render :show, status: :created, location: #ticket }
else
format.html { render :new }
format.json { render json: #ticket.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /tickets/1
# PATCH/PUT /tickets/1.json
def update
respond_to do |format|
if #ticket.update(ticket_params)
format.html { redirect_to #ticket, notice: 'Ticket was successfully updated.' }
format.json { render :show, status: :ok, location: #ticket }
else
format.html { render :edit }
format.json { render json: #ticket.errors, status: :unprocessable_entity }
end
end
end
# DELETE /tickets/1
# DELETE /tickets/1.json
def destroy
#ticket.destroy
respond_to do |format|
format.html { redirect_to tickets_url, notice: 'Ticket was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_ticket
#ticket = Ticket.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def ticket_params
params.require(:ticket).permit(:subject, :subsubject, :user_id, ticketissues_attributes: [
:body, :id, :_destroy] )
#params.require(:ticket).permit!
end
end
and my view is like this
<%= f.input :subject , collection: [ "تغییر اطلاعات کسب و کار",
"تغییر اطلاعات یک کوپن",
"سایر موارد"] %>
<%= f.input :subsubject %>
<!-- <%= f.association :user %> -->
</div>
<%= f.simple_fields_for :ticketissue do |p| %>
<%= p.input :body %>
<% end %>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
but when i want to create a ticket , form will not save to database
and i get this error:
Started POST "/tickets" for 127.0.0.1 at 2017-04-11 23:52:33 +0430
Processing by TicketsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"fsl6nTe0PjmBKpeuh16BRFlYOw0MB93LEYDVEAl6TtT/uu/LwGTA0P2q0bRxIxBUqHqZINXHntrZLt7MuCG84Q==", "ticket"=>{"subject"=>"تغییر اطلاعات کسب و کار", "subsubject"=>"lk", "ticketissue"=>{"body"=>"lkjkjkjkjkkjkj"}}, "commit"=>"Create Ticket"}
Unpermitted parameter: ticketissue
but when i use console and this command:
Ticket.create(subject: 'test' , subsubject: 'ticket test' , ticketissues_attributes: [{body: "[some thing" }] )
every things work fines and all data save.
tanks for read and help.
You must use the plural here
= f.simple_fields_for :ticketissues do |p|
I have a model "post" and a model "photo". The model post have a nested form from photo to upload images with association. The upload works fine, but everytime I go to edit the post, I have a new input to each image uploaded and one more input to upload a new image. I want to have just the input to upload a new file and hide or not load the others.
Here is my code:
<%= f.fields_for :photos do |photo| %>
<%= photo.file_field :image, class: "form-control" %>
<% end %>
Controller:
module Admin
class SeminovosController < SuperAdminController
before_action :set_seminovo, only: [:show, :edit, :update, :destroy]
# GET /seminovos
# GET /seminovos.json
def index
#seminovos = Seminovo.all
#seminovo = Seminovo.new
#seminovo.photos.build
#expires_in 3.hours, :public => true, 'max-stale' => 0
end
# GET /seminovos/1
# GET /seminovos/1.json
def show
end
# GET /seminovos/new
def new
#seminovo = Seminovo.new
#seminovo.photos.build
#seminovo.photos
end
# GET /seminovos/1/edit
def edit
#seminovo.photos.build
#seminovo.photos
end
# POST /seminovos
# POST /seminovos.json
def create
##seminovo = Seminovo.new(seminovo_params)
respond_to do |format|
#seminovo = Seminovo.new(seminovo_params)
#seminovo.save
format.html { redirect_to #seminovo }
format.js
# if #seminovo.save
# format.html { redirect_to #seminovo, notice: 'Seminovo was successfully created.' }
# format.json { render :show, status: :created, location: #seminovo }
# else
# format.html { render :new }
# format.json { render json: #seminovo.errors, status: :unprocessable_entity }
# end
end
end
# PATCH/PUT /seminovos/1
# PATCH/PUT /seminovos/1.json
def update
respond_to do |format|
if #seminovo.update(seminovo_params)
format.html { redirect_to #seminovo, notice: 'Seminovo was successfully updated.' }
format.json { render :show, status: :ok, location: #seminovo }
else
format.html { render :edit }
format.json { render json: #seminovo.errors, status: :unprocessable_entity }
end
end
end
# DELETE /seminovos/1
# DELETE /seminovos/1.json
def destroy
#seminovo.destroy
respond_to do |format|
format.html { redirect_to seminovos_url, notice: 'Seminovo was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_seminovo
#seminovo = Seminovo.friendly.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def seminovo_params
params.require(:seminovo).permit(:name, :price, :marca_id, :tipo_id, :ano_modelo,
:portas, :km_rodados, :combustivel, :placa, :cor, :desc,
:video, :destaque, :photo_id, :slug,
photos_attributes: [ :id, :image, :image_uid, :image_name, :desc,
:seminovos_id, :_destroy ])
end
end
end
Remove
#seminovo.photos.build
#seminovo.photos
from new and edit action.
Then replace
<%= f.fields_for :photos do |photo| %>
<%= photo.file_field :image, class: "form-control" %>
<% end %>
With
<%= f.fields_for :photos, #seminovo.photos.new do |photo| %>
<%= photo.file_field :image, class: "form-control" %>
<% end %>
I'm not sure if this is even possible using Carrierwave, I'm still learning my way around Ruby and Rails so bear with me.
I have a simple form to record observations. Each observation has data that can be recorded against it and I store this in a JSONB column within the observation (I will eventually store multiple sets of data against an observation). I want to be able to upload an image through Carrierwave and store it with the data within the JSONB column rather than saving it to its own column. So my saved data for this column would be like this for example...
{
"ph":"",
"ecoli":"",
"nitri":"Less than 0.5",
"oxygen":"",
"clarity":"bottom visible",
"nitrates":"Less than 0.5",
"conditions":[
"Wildlife Death",
"Shoreline Alterations",
"Water Quality"
],
"observed_on":"2015-06-21T04:45",
"invasive_species":[
"Phragmites",
"Loosestrife",
"Dog-Strangling Vine"
],
"phosphates_threshold":"less than 0.2",
"image":[
"url": "the/url",
"thumbnail: "the/thumbnail/url",
"medium":"the/thumbnail/url"
.....
]
}
Some of the supporting code for reference...
observation.rb
class Observation < ActiveRecord::Base
belongs_to :user
has_many :comments
serialize :observation_data, HashSerializer
store_accessor :observation_data
end
observation_data.rb - tableless model
class ObservationData < ActiveRecord::Base
belongs_to :observation
mount_uploader :image, ImageUploader
end
_form.html.erb
<%= form_for #observation do |f| -%>
...Other form items
<fieldset>
<legend>Observation data</legend>
<%= render "observation_data", :f => f %>
</fieldset>
<div class="actions">
<%= f.submit "Submit", class: "button" %>
</div>
<% end %>
_observation_data.html.erb
<%= f.fields_for :observation_data, OpenStruct.new(#observation.observation_data) do |o| %>
...Other form items
<div class="field">
<%= o.label :image, "Upload an image" %>
<%= o.file_field :image %>
</div>
...Other form items
<% end %>
observations_controller.rb
class ObservationsController < ApplicationController
before_action :set_observation, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
def index
#observations = Observation.all
#user = current_user.id
end
def show
#observations = Observation.find_by(id: params[:id])
#observation_data = #observation.observation_data
#comments = #observation.comments.all
#comment = #observation.comments.build
#user = User.find_by(id: #observation.user_id)
end
def new
#observation = Observation.new
end
def edit
end
def create
#observation = Observation.new(observation_params)
#observation.user_id = current_user.id
respond_to do |format|
if #observation.save
format.html { redirect_to #observation, notice: 'Observation was successfully created.' }
format.json { render action: 'show', status: :created, location: #idea }
else
format.html { render action: 'new' }
format.json { render json: #observation.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #observation.update(observation_params)
format.html { redirect_to #observation, notice: 'Observation was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #observation.errors, status: :unprocessable_entity }
end
end
end
def destroy
#observation.destroy
respond_to do |format|
format.html { redirect_to root_url }
format.json { head :no_content }
end
end
private
def set_observation
#observation = Observation.find(params[:id])
end
def observation_params
params.require(:observation).permit(:user_id, :lat, :lng, :name, :description, :comment, observation_data: [:observed_on, :image, :ph, :oxygen, :ecoli, :phosphates_threshold, :clarity, :nitri, :nitrates, wildlife: [], conditions: [], invasive_species: []])
end
end
The problem for me is mount_uploader :image, ImageUploader is always looking for an :image column, how can I merge the Carrierwave response this with JSON in another column? Is it even possible?
I'm fairly new to rails, building my first app. I'm running rails 4 w/ bootstrap 3. I'm trying to get a complex form to work. I have two models:
class Employee < ActiveRecord::Base
belongs_to :company
belongs_to :user, :through => :company
has_one :position
accepts_nested_attributes_for :position
end
class Position < ActiveRecord::Base
belongs_to :employees
accepts_nested_attributes_for :employees
end
I have a form where the User can create a new job title (Position Model) and select the employees (Employees Model) that position will be applied to. Basically it's a single form that will add fields to 2 different database tables (Position and Employee).
This is my view:
<%= simple_form_for(#position) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :job_title %>
<%= f.input :job_description %>
</div>
<%= f.fields_for :Employee do |f| %>
<%= f.input :employee_title, label: "Apply to:", collection: Employee.all, label_method: :first_name, as: :check_boxes %>
<% end %>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
Below are the controllers:
class PositionsController < ApplicationController
before_action :set_position, only: [:show, :edit, :update, :destroy]
# GET /positions
# GET /positions.json
def index
#positions = Position.all
end
# GET /positions/1
# GET /positions/1.json
def show
end
# GET /positions/new
def new
#position = Position.new
end
# GET /positions/1/edit
def edit
end
# POST /positions
# POST /positions.json
def create
#position = Position.new(position_params)
respond_to do |format|
if #position.save
format.html { redirect_to #position, notice: 'position was successfully created.' }
format.json { render action: 'show', status: :created, location: #position }
else
format.html { render action: 'new' }
format.json { render json: #position.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /positions/1
# PATCH/PUT /positions/1.json
def update
respond_to do |format|
if #position.update(position_params)
format.html { redirect_to #position, notice: 'position was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #position.errors, status: :unprocessable_entity }
end
end
end
# DELETE /positions/1
# DELETE /positions/1.json
def destroy
#position.destroy
respond_to do |format|
format.html { redirect_to positions_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_position
#position = Position.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def position_params
params.require(:position).permit(:position_title, :position_description, :position_create_date)
end
end
class EmployeesController < ApplicationController
# encoding: UTF-8
before_action :set_employee, only: [:show, :edit, :update, :destroy]
# GET /employees
# GET /employees.json
def index
#employees = Employee.all
end
# GET /employees/1
# GET /employees/1.json
def show
end
# GET /employees/new
def new
#employee = Employee.new
end
# GET /employees/1/edit
def edit
end
# POST /employees
# POST /employees.json
def create
#employee = Employee.new(employee_params)
respond_to do |format|
if #employee.save
format.html { redirect_to #employee, notice: 'Employee was successfully created.' }
format.json { render action: 'show', status: :created, location: #employee }
else
format.html { render action: 'new' }
format.json { render json: #employee.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /employees/1
# PATCH/PUT /employees/1.json
def update
respond_to do |format|
if #employee.update(employee_params)
format.html { redirect_to #employee, notice: 'Employee was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #employee.errors, status: :unprocessable_entity }
end
end
end
# DELETE /employees/1
# DELETE /employees/1.json
def destroy
#employee.destroy
respond_to do |format|
format.html { redirect_to employees_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_employee
#employee = Employee.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def employee_params
params.require(:employee).permit(:first_name, :last_name, :employee_title)
end
end
The problem I'm facing is I get the form to render perfectly, but when I submit it, only fields that belong to the Position model get recorded. The :employee_title stays blank. Any suggestions what the problem is?
Thank you!!
Too many points to fit in a comment:
belongs_to :employees should be singular: belongs_to :employee
Your fields_for should be like (differentiate the ff from parent form):
<%= f.fields_for :Employee do |ff| %>
<%= ff.input :employee_title, label: "Apply to:", collection: Employee.all,
label_method: :first_name, as: :check_boxes %>
<% end %>
If it doesn't work, supply your controller also and I'll update my answer.
Edit:
After seeing your controllers, it seems most likely to be case of unpermitted params.
In position_controller.rb add employee params to position params
def position_params
params.require(:position).permit(:position_title, :position_description, :position_create_date, employees_attributes: [:first_name, :last_name, :employee_title])
end
I am using text-editor(wysihtml5).I am having problem in saving data in database.If I have typed more than 20 lines. it shows error like " Mysql2::Error: Data too long for column 'description' at row 1".and I am using rails4.
In Model
class News < ActiveRecord::Base
attr_accessible :name,:published_on,:description
#associations
validates :name, presence: true
validates :published_on, presence: true
validates :description, presence: true
end
In Controller
class NewsController < ApplicationController
layout :setting_layout
before_action :set_news, only: [:show, :edit, :update, :destroy]
# GET /news
# GET /news.json
def index
#news = News.all
end
# GET /news/1
# GET /news/1.json
def show
end
# GET /news/new
def new
#news = News.new
end
# GET /news/1/edit
def edit
end
# POST /news
# POST /news.json
def create
#news = News.new(news_params)
respond_to do |format|
if #news.save
format.html { redirect_to #news, notice: 'News was successfully created.' }
format.json { render action: 'show', status: :created, location: #news }
else
format.html { render action: 'new' }
format.json { render json: #news.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /news/1
# PATCH/PUT /news/1.json
def update
respond_to do |format|
if #news.update(news_params)
format.html { redirect_to #news, notice: 'News was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #news.errors, status: :unprocessable_entity }
end
end
end
# DELETE /news/1
# DELETE /news/1.json
def destroy
#news.destroy
respond_to do |format|
format.html { redirect_to news_index_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_news
#news = News.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def news_params
params.require(:news).permit(:name, :published_on, :description)
end
end
In View
<%= simple_form_for #news, html: {class: 'form-inline form-horizontal'}, :validate => true do |f|%>
<p><font color="red">Fields with * are required.</font></p>
<div class="inputs">
<%= f.input :name %>
<%= f.input :published_on, as: 'string', input_html: {class: 'datepicker'} %>
<%= f.input :description, as: 'text', :input_html =>{:rows => '100', :cols => '100', :class => 'input wysihtml5' }%>
</div>
<div class="form-actions">
<%= button_tag(type: 'submit', class: "btn btn-primary") do %>
<i class="icon-ok icon-white"></i> Save
<% end %>
</div>
<% end %>
In Js file
$(document).ready(function(){
$(".wysihtml5").wysihtml5();
})
In view I have given row and cols value. But it takes only cols value.
You have probably set it as a string in your migration file, rather than text.
string fields are interpreted as varchar, and are limited in character length. text fields are not.
if the field is text, change it to longtext e.g.
change_column :your_table, :your_column, :longtext