I'm creating a form in which I create related records, so far it works pretty well, it creates the nested records but when I create them it shows in the same form the related records created before, I just need to save records and not show the ones created in the textfields, how can I do that? this is my form
<%= form_with(model: drugs_device, local: true, html: {class: "formulario_validado"}) do |form| %>
<div class="form-row">
<div class="form-group col-md-6">
<%= form.label :abbreviation,"Código / ATC" %>
<%= form.text_field :abbreviation, class:"form-control", required: "true"%>
</div>
<%=form.fields_for :detail_drugs_devices do |fd| %>
<div class="form-row">
<div class="form-group col-md-3">
<%= fd.label :drug_concentration,"Concentration:" %>
<%= fd.text_field :drug_concentration, class:"form-control" %>
</div>
<div class="form-group col-md-3">
<%= fd.label :route_id,"Vía de administración" %>
<%= fd.select :route_id, options_for_select(#routes.map{|e|[e.description, e.id]}), {:prompt => "Por favor seleccione"}, {:class => "form-control"} %>
</div>
</div>
<%end%>
<div class="row">
<div class="col-md-4 offset-md-8 ">
<%= submit_tag "Guardar", class: "btn btn-primary"%>
</div>
</div>
</div>
<%end%>
my model drugs_device:
class DrugsDevice < ApplicationRecord
belongs_to :group
has_many :detail_drugs_devices
accepts_nested_attributes_for :detail_drugs_devices, reject_if: proc { |attributes| attributes['pharmaceutical_form_id'].blank?}
end
my model DetailDrugsDevice
class DetailDrugsDevice < ApplicationRecord
belongs_to :drugs_device
belongs_to :pharmaceutical_form
belongs_to :unit_size
belongs_to :route
end
my controller:
class DrugsDevicesController < ApplicationController
before_action :set_drugs_device, only: [:show, :edit, :update, :destroy]
# GET /drugs_devices
# GET /drugs_devices.json
def index
##drugs_devices = DrugsDevice.Busqueda_general(params).paginate(page: params[:page]).per_page(3)
#drugs_devices = DrugsDevice.all.paginate(page: params[:page]).per_page(3)
end
# GET /drugs_devices/1
# GET /drugs_devices/1.json
def show
end
# GET /drugs_devices/new
def new
#drugs_device = DrugsDevice.new
#drugs_device.detail_drugs_devices.build
#grupos = Group.all
#pharmaceutical_forms = PharmaceuticalForm.all
#unit_sizes = UnitSize.all
#routes = Route.all
end
# GET /drugs_devices/1/edit
def edit
#drugs_device.detail_drugs_devices.build
#grupos = Group.all
#pharmaceutical_forms = PharmaceuticalForm.all
#unit_sizes = UnitSize.all
#routes = Route.all
end
# POST /drugs_devices
# POST /drugs_devices.json
def create
#drugs_device = DrugsDevice.new(drugs_device_params)
respond_to do |format|
if #drugs_device.save
format.html { redirect_to edit_drugs_device_path(#drugs_device), notice: 'Drugs device was successfully created.' }
format.json { render :show, status: :created, location: #drugs_device }
else
format.html { render :new }
format.json { render json: #drugs_device.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /drugs_devices/1
# PATCH/PUT /drugs_devices/1.json
def update
respond_to do |format|
if #drugs_device.update(drugs_device_params)
format.html { redirect_to edit_drugs_device_path(#drugs_device), notice: 'Drugs device was successfully updated.' }
format.json { render :show, status: :ok, location: #drugs_device }
else
format.html { render :edit }
format.json { render json: #drugs_device.errors, status: :unprocessable_entity }
end
end
end
# DELETE /drugs_devices/1
# DELETE /drugs_devices/1.json
def destroy
#drugs_device.destroy
respond_to do |format|
format.html { redirect_to drugs_devices_url, notice: 'Drugs device was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_drugs_device
#drugs_device = DrugsDevice.find(params[:id])
end
# Only allow a list of trusted parameters through.
def drugs_device_params
params.require(:drugs_device).permit(:group_id, :atc, :abbreviation, :cientific_name, :stated_at, detail_drugs_devices_attributes: [:pharmaceutical_form_id, :unit_size_id, :route_id, :drug_concentration, :id])
end
end
Related
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
I am trying to improve an exercice that I did on treehouse, the idea was to remake a little version of facebook thing, where users could publish statuses.
Now I want that a user can comment any statuses... And I am kinda lost...
The idea is to have all on the same page (if possible?, like on the real facebook)
So the comment form and the "displaying" content...
I hope anyone could help me :)
This is my github repository
I think I haven't understand how to call variables from a controller to another...
If someone could explain me with very easy words ... I am not native english speaker... so sometime it's difficult..
Here are the statuses part
controllers/statuses_controller/rb
class StatusesController < ApplicationController
before_filter :authenticate_user!, only: [:new, :create, :edit, :update]
before_action :set_status, only: [:show, :edit, :update, :destroy]
def index
#statuses = Status.all
#comments = Comment.all
end
def show
#status = Status.find(params[:id])
#comments = #status.comments.all
end
def new
#status = Status.new
#comment = #status.comments.build
end
def create
#status = Status.new(status_params)
#status.user = current_user
respond_to do |format|
if #status.save
format.html { redirect_to #status, notice: 'Status was successfully created.' }
format.json { render :show, status: :created, location: #status }
else
format.html { render :new }
format.json { render json: #status.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #status.update(status_params)
format.html { redirect_to #status, notice: 'Status was successfully updated.' }
format.json { render :show, status: :ok, location: #status }
else
format.html { render :edit }
format.json { render json: #status.errors, status: :unprocessable_entity }
end
end
end
def destroy
#status.destroy
respond_to do |format|
format.html { redirect_to statuses_url, notice: 'Status was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_status
#status = Status.find(params[:id])
end
def status_params
params.require(:status).permit(:user_id, :content, :comments_attribute[:id, :status_id, :content])
end
end
models/status.rb
class Status < ActiveRecord::Base
belongs_to :user
has_many :comments
default_scope -> { order(created_at: :DESC)}
validates :content, presence: true,
length: {minimum: 2}
validates :user_id, presence: true
end
views/comments/_form.html.erb I create a render in my index below:
<% simple_form_for #status.comments do |f|%>
<%= f.input :content %>
<%= f.button :submit %>
<% end %>
view/statuses/index.html.erb
<div class="page-header">
<h1>All of the Statuses</h1>
</div>
<%= link_to "Post A New Status", new_status_path, class: "btn btn-success"%>
<br>
<br>
<% #statuses.each do |status| %>
<div class="status">
<div class="row">
<div class="col-xs-1 avatar">
<%= image_tag status.user.avatar.thumb if status.user.avatar?%>
</div>
<div class="col-xs-7">
<h4><%= status.user.full_name%></h4>
</div>
</div>
<div class="row">
<div class="col-xs-8">
<p><%= simple_format(status.content) %></p>
</div>
</div>
<div class="row">
<div class="col-xs-8">
<%= link_to time_ago_in_words(status.created_at) + " ago", status %>
<% if status.user == current_user %>
<span class="admin">
| <%= link_to "Edit", edit_status_path(status) %> |
<%= link_to "Delete", status, method: :delete, data: {confirm: "Are you sure?"} %>
</span>
<% end %>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<p>Comments</p>
<% #comments.each do |comment| %>
<%= comment.content %>
<% end %>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<%= render "comments/form" %>
</div>
</div>
</div>
Now the comments part:
model/comment.rb
class Comment < ActiveRecord::Base
belongs_to :status
belongs_to :user
end
controllers/comments_controller.rb
class CommentsController < ApplicationController
def create
#comment = Comment.new(params_comment)
end
def index
#statuses = Status.all
#comments = Comment.all
#comment = Comment.find_by(params[:id])
end
private
def params_comment
params.require(:comment).permit(:content)
end
end
routes.rb
resources :statuses do
resources :comments
end
user.rb
that's a part of what I have in there
has_many :statuses
has_many :comments
your comments creation method should look like this:
#status = Status.find(params[:status_id])
#comment = #status.comments.create(comment_params)
#comment.user_id = current_user.id if current_user
#comment.save
I am trying to make an app in Rails 4.
I use simple form with Cocoon gem.
In development mode, I have all of this working correctly, however in production mode its a big mess.
I have profile model and a qualifications model.
The associations are:
profile.rb
has_many :qualifications
accepts_nested_attributes_for :qualifications, reject_if: :all_blank, allow_destroy: true
qualification.rb
belongs_to :profile
In my profiles new form, I have:
<%= simple_form_for(#profile, multipart: true) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<div class="intpol2">
Your professional qualifications
</div>
<%= f.simple_fields_for :qualifications do |f| %>
<%= render 'qualifications/qualification_fields', f: f %>
<% end %>
</div>
<div class="row">
<div class="col-md-6">
<%= link_to_add_association 'Add a qualification', f, :qualifications, partial: 'qualifications/qualification_fields' %>
</div>
</div>
<div class="row">
In my qualifications fields new form, I have:
<div class="nested-fields">
<div class="container-fluid">
<div class="form-inputs">
<div class="row">
<div class="col-md-6">
<%= f.input :title, :label => "Your award" %>
</div>
<div class="col-md-6">
</div>
</div>
<div class="row">
<div class="col-md-6">
<%= f.input :level, collection: [ "Bachelor's degree", "Master's degree", "Ph.D", "Post Doctoral award"] %>
</div>
<div class="col-md-6">
<%= f.input :year_earned, :label => "When did you graduate?", collection: (Date.today.year - 50)..(Date.today.year) %>
</div>
</div>
<div class="row">
<div class="col-md-6">
<%= link_to_remove_association 'Remove this qualification', f %>
</div>
</div>
</div>
</div>
</div>
In development, when I click the link to add a new qualification, it reloads the profile new form, but does not reveal the qualifications field form.
I have the same setup with address model (same as qualification).
All of this works in development, but not in production.
Is there an extra step required to get this working in production?
My qualifications controller:
class QualificationsController < ApplicationController
before_action :set_qualification, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
# GET /qualifications
# GET /qualifications.json
def index
#qualifications = Qualification.all
authorize #qualifications
end
# GET /qualifications/1
# GET /qualifications/1.json
def show
end
# GET /qualifications/new
def new
#qualification = Qualification.new
authorize #qualification
end
# GET /qualifications/1/edit
def edit
end
# POST /qualifications
# POST /qualifications.json
def create
#qualification = Qualification.new(qualification_params)
authorize #qualification
respond_to do |format|
if #qualification.save
format.html { redirect_to #qualification }
format.json { render :show, status: :created, location: #qualification }
else
format.html { render :new }
format.json { render json: #qualification.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /qualifications/1
# PATCH/PUT /qualifications/1.json
def update
respond_to do |format|
if #qualification.update(qualification_params)
format.html { redirect_to #qualification }
format.json { render :show, status: :ok, location: #qualification }
else
format.html { render :edit }
format.json { render json: #qualification.errors, status: :unprocessable_entity }
end
end
end
# DELETE /qualifications/1
# DELETE /qualifications/1.json
def destroy
#qualification.destroy
respond_to do |format|
format.html { redirect_to qualifications_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_qualification
#qualification = Qualification.find(params[:id])
authorize #qualification
end
# Never trust parameters from the scary internet, only allow the white list through.
def qualification_params
params[:qualification].permit(:profile_id, :level, :title, :year_earned, :institution)
end
end
My profiles controller:
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
after_action :verify_authorized
# GET /profiles
# GET /profiles.json
def index
#profiles = Profile.all
authorize #profiles
end
# GET /profiles/1
# GET /profiles/1.json
def show
end
# GET /profiles/new
def new
#profile = Profile.new
#profile.qualifications.build
#profile.visions.build
#profile.personalities.build
#profile.addresses.build
authorize #profile
end
# GET /profiles/1/edit
def edit
end
# POST /profiles
# POST /profiles.json
def create
#profile = Profile.new(profile_params)
authorize #profile
respond_to do |format|
if #profile.save
format.html { redirect_to #profile }
format.json { render :show, status: :created, location: #profile }
else
format.html { render :new }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /profiles/1
# PATCH/PUT /profiles/1.json
def update
respond_to do |format|
if #profile.update(profile_params)
format.html { redirect_to #profile }
format.json { render :show, status: :ok, location: #profile }
else
format.html { render :edit }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# DELETE /profiles/1
# DELETE /profiles/1.json
def destroy
#profile.destroy
respond_to do |format|
format.html { redirect_to profiles_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_profile
#profile = Profile.find(params[:id])
authorize #profile
end
# Never trust parameters from the scary internet, only allow the white list through.
def profile_params
params.require(:profile).permit(:user_id, :title, :hero, :overview, :research_interest, :occupation, :external_profile,
:working_languages, :tag_list,
user_attributes: [:avatar],
personality_attributes: [:average_day, :fantasy_project, :preferred_style],
vision_attributes: [:long_term, :immediate_challenge],
qualifications_attributes: [:id, :level, :title, :year_earned, :institution, :_destroy],
addresses_attributes: [:id, :unit, :building, :street_number, :street, :city, :region, :zip, :country, :latitude, :longitude, :_destroy] )
end
end
This was solved when I precompiled my assets
I want to creat a classified ads website for a project in school and I try to create a form to send a message by email at a member of the website. The email adress is contained in a model which is name "Membre" and this model is link at a model who is name "Annonce" which contained the ad.
But when I try to create that, I have this error :
param is missing or the value is empty: annonce
app/controllers/annonces_controller.rb:104:in `annonce_params'
app/controllers/annonces_controller.rb:29:in `create'
Here the Ad controller :
class AnnoncesController < ApplicationController
before_action :set_annonce, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!, :except => [:index]
# GET /annonces
# GET /annonces.json
def index
#annonces = Annonce.all
end
# GET /annonces/1
# GET /annonces/1.json
def show
end
# GET /annonces/new
def new
#annonce = Annonce.new
end
# GET /annonces/1/edit
def edit
end
# POST /annonces
# POST /annonces.json
def create
#annonce = Annonce.new(annonce_params)
#annonce.membre_id = current_membre.id
respond_to do |format|
if #annonce.save
format.html { redirect_to #annonce, notice: t('annonce_cree_succes') }
format.json { render :show, status: :created, location: #annonce }
else
format.html { render :new }
format.json { render json: #annonce.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /annonces/1
# PATCH/PUT /annonces/1.json
def update
respond_to do |format|
if #annonce.update(annonce_params)
format.html { redirect_to #annonce, notice: t('annonce_cree_succes') }
format.json { render :show, status: :ok, location: #annonce }
else
format.html { render :edit }
format.json { render json: #annonce.errors, status: :unprocessable_entity }
end
end
end
# DELETE /annonces/1
# DELETE /annonces/1.json
def destroy
#annonce.destroy
respond_to do |format|
format.html { redirect_to annonces_url, notice: t('annonce_destroy_succes') }
format.json { head :no_content }
end
end
# GET /annonces/contact/1
def contact
#form_contact = FormContact.new
if #form_contact.valid?
#MembreMailer.email_contact(Membre.where(:id => #annonce.membre_id ),current_membre,#annonce,#message)
#annonce = Annonce.find(params[:id])
#recepteur = Membre.where(:id => #annonce.membre_id )
#membre = current_membre
mail(:to => "#{recepteur.pseudo} <#{recepteur.email}>", subject: 'Reponse à l\'une de vos annnonces')
redirect_to root
end
end
# GET /annonces/report/1
def report
#annonce = Annonce.find(params[:id])
end
private
def authenticate_user!
if membre_signed_in?
#super
else
redirect_to login_path, :notice => 'Merci de vous connecter pour effecter cette action'
## if you want render 404 page
## render :file => File.join(Rails.root, 'public/404'), :formats => [:html], :status => 404, :layout => false
end
end
# Use callbacks to share common setup or constraints between actions.
def set_annonce
#annonce = Annonce.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def annonce_params
params.require(:annonce).permit(:id, :titre, :corps, :prix, :membre_id, :categorie, :created_at, :image)
end
Here the view contact :
<div class="col-md-offset-2 col-md-8 well panel panel-default">
<h2 class='panel-heading text-center'><%= t('contacter') %></h2>
<div class="panel-body text-center">
<%= form_for(:form_contact, :url => {:action => :create}) do |f| %>
<div class="field block-center">
<%= f.label "message" %></br>
<%= f.text_area(:message, size: "50x15")%>
</div></br>
<div class="actions form-group col-md-offset-3 col-md-6">
<%= submit_tag t('envoyer'), :class => "btn btn-large btn-block btn-primary" %>
</div>
<% end %>
</div>
</div>
<p class='row'> </p>
And here the FormContact class:
class FormContact < ActiveForm::Base
attr_accessor :message
validates_presence_of :message
def new
#form_contact = FormContact.new(login_form)
end
def index
#form_contact = FormContact.new
end
private
def login_form
params.require(:form_contact).permit(:message)
end
end
How can I fix that ?
Thanks in advance
This is routing error, you should call the create method of FormContactsController, not AnnoncesController create method.
<%= form_for(:form_contact, :url => {:controller => "FormContactsController", :action => :create}) do |f| %>
My Rails application have two model. Location and Post, Location have many post.I am Using
ancestry gem.
class Post < ActiveRecord::Base
belongs_to :location, :counter_cache => true
end
class Location < ActiveRecord::Base
include Tree
has_ancestry :cache_depth => true
has_many :posts
end
My Post Controller
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
def index
#posts = Post.all
end
def show
end
def new
#post = Post.new
end
def edit
end
def create
#post = Post.new(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render action: 'show', status: :created, location: #post }
else
format.html { render action: 'new' }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:name)
end
end
If i am create new Post with which Location belongs in _form.html.erb
<%= form_for(#post) do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved: </h2>
<ul>
<% #post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<%= select :location_id, Location.all.at_depth(4) { |l| [ l.name, l.id ] } %>
<div class="actions">
<%= f.submit %>
</div>
Browser show error message which is display bellow
ArgumentError in Posts#new
Not sure if this fixes your error, but:
To make the dropdown working, change the select line to:
<%= f.select :location_id, Location.all.at_depth(4) { |l| [ l.name, l.id ] } %>
This is because you want the formbuilder f to handle the creation of the form element.
You also have to whitelist the :location_id parameter in the controller:
def post_params
params.require(:post).permit(:name, :location_id)
end