Reputation: 331
⚠️ "error param is missing or the value is empty: credit" ⚠️
I can't find the correct syntax to provide the instance to the polymorphic table. The problem is inside my controller I guess Project(action create & new).
But when I'm starting to do that within my view I have some issues and
I can't figure out the right syntax.
🔥 => to create the credit instance through the project form
🔥 => And for sure I can't display and update those instance
🙏🏻
Project has_many credits, as creditable
Profile has_many credits, as creditable
Credit belongs_to :creditable, polymorphic: true
# in this post we will focus on a form which include @credit
# inside a @project form
# so I let the @profile for now but I will use it later
resources :projects do
resources :credits, only: [:create, :edit, :update, :destroy]
end
For instance let's say that I would like to display a single form for @project which include field for some credit attributes (like content, link, category).
My objective it to create that project instance and also its nested attributes for credits.
=> the form is inside Project_new ProjectController action new /create...
<%= simple_form_for @project do |f| %>
<div class="content-form">
<div class="form-inputs">
<%= f.simple_fields_for :credit do |credit_form| %>
<%= credit_form.hidden_field :creditable_type, :value => @creditable_type %>
<%= credit_form.input :category %>
<%= credit_form.input :content %>
<%= credit_form.input :link %>
<% end %>
<%= f.input :name, label: false, placeholder: "nom du project" %>
<%= f.input :year, label: false, placeholder: "Année de création" %>
<%= f.input :description, label: false, placeholder: "Une description" %>
<label class="super-label">
<%= f.input :mainphoto, input_html: {preview_version: :thumb}, label: false, id: "over-btn" %>
<%= f.attachinary_file_field :photos, as: :attachinary, cloudinary: {use_filename: true, unique_filename: false}, label: false, id: "over-btn" %>
<div class="form-actionss">
<%= f.button :submit, class: "btn-main-romain" %>
</div>
</label>
<p id="filename hidden"></p>
</div>
</div>
<% end %>
class Profile < ApplicationRecord
belongs_to :user
has_many :credits, :as => {:creditable => 'profile'}, :dependent => :destroy, autosave: true
has_attachment :photo
end
class Project < ApplicationRecord
#validates :name, presence:true
#validates :year, presence:true
#validates :description, presence:true
has_many :credits, :as => {:creditable => 'project'}, :dependent => :destroy, autosave: true
attr_accessor :link
attr_accessor :category
attr_accessor :content
accepts_nested_attributes_for :credits
has_attachments :photos, maximum: 10
mount_uploader :mainphoto, PhotoUploader
end
class Credit < ApplicationRecord
belongs_to :creditable, polymorphic: true
end
create_table "credits", force: :cascade do |t|
t.string "category"
t.string "content"
t.string "link"
t.string "creditable_type"
t.integer "creditable_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "projects", force: :cascade do |t|
t.string "name"
t.integer "year"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "place"
t.string "mainphoto"
end
create_table "profiles", force: :cascade do |t|
t.bigint "user_id"
t.string "photo"
t.string "cell_phone"
t.string "city"
t.string "email"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "first_name"
t.string "last_name"
t.integer "zip_code"
t.string "street"
t.string "coutry"
t.index ["user_id"], name: "index_profiles_on_user_id"
end
=> Everything seams to be fine.
#create an instance of project
[1] Project.create(name:'project1')
=> #<Project:0x007fb3d7a64e78
id: 15,
name: "project1",
year: nil,
description: nil,
created_at: Sun, 04 Feb 2018 12:09:29 UTC +00:00,
updated_at: Sun, 04 Feb 2018 12:09:29 UTC +00:00,
place: nil,
mainphoto: nil>
#put that instance of project inside a variable called "p"
[2] p = Project.last
...
#create an instance of credit with an instance of project ("p") as
attribute
[3] Credit.create(category:'webmaster', creditable:p)
=> #<Credit:0x007fb3d0f9e4e0
id: 1,
category: "webmaster",
content: nil,
link: nil,
creditable_type: "Project",
creditable_id: 15,
# check if it's possible to pick up back the project instance
[5] Credit.last.creditable
=> #<Project:0x007fb3d0e827c8
id: 15,
name: "project1",
year: nil,
description: nil,
created_at: Sun, 04 Feb 2018 12:09:29 UTC +00:00,
updated_at: Sun, 04 Feb 2018 12:09:29 UTC +00:00,
place: nil,
mainphoto: nil
class ProjectsController < ApplicationController
skip_before_action :authenticate_user!, only: [:index]
before_action :set_project, only:[:show, :edit, :update, :destroy]
layout "application", only: [:index, :destroy,:show,]
layout "devise", only: [ :create, :new, :edit, :update ]
def index
@projects = Project.all
@profile = User.find(1).profile
end
def show
end
def new
@project = Project.new
@credit = Credit.new
@creditable_type = "project"
end
def create
@project = Project.create(project_params)
@credit = Credit.create(credit_params) #syntax pblm here
creditable = params["project"]["credit"]["creditable_type"]
#category = params["project"]["credit"]["category"]
#link = params["project"]["credit"]["link"]
#content = params["project"]["credit"]["content"]
#allcreditables = {creditable,category,link,content}
#@project.credits.create(allcreditables)
#something like ...
#@credit = @project.credits.create...
# give me an error like ERROR "no implicit conversion of symbol
# into string"
if @project.save
redirect_to @project
else
render :new
end
end
def edit
end
def update
@project.update(project_params)
if @project.save
redirect_to @project
else
render :edit
end
end
def destroy
@project.destroy
redirect_to projects_path
flash[:notice] = "Le project - #{@project.name} - à bien été supprimé"
end
private
def set_project
@project = Project.find(params[:id])
@projects = Project.all
@profile = User.find(1).profile
end
def credit_params
params.require(:credit)
.permit(:link,
:category,
:content,
:creditable_type)
.merge(project: @project)
end
def project_params
params.require(:project).permit(
:name,
:year,
:place,
:description,
:mainphoto,
photos: [],
:credits_attributes => [:link,:category,:content])
end
end
⚠️ 💀 the problem comes form the new and create method, I tried to do something with credit_params, but at the end @project is recorded but @Project.credits is not. I can't get the trick. Credits_attributes are inside a hash and hard for me to figure out back the way to pick them.
{
"utf8"=>"✓", "authenticity_token"=>"WKAiVi3xbzi8GpcISADZb2e3GvEut230QtmWnfPdEpFqz9ko2kuzXxHFnjufqaMfrESr96Qg33TtvIOPuv/bQw==", "project"=>
{
"credit"=>{
"category"=>"Photographer",
"content"=>"These photos have been taken by Martin Polak, Main photographer at ECAL, DesignSchool, Lauzane",
"link"=>"www.martinpolak.com"
},
"name"=>"Adidas By ECAL ",
"year"=>"2015",
"description"=>"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book",
"photos"=>[""]
},
"commit"=>"Create Project",
"controller"=>"projects",
"action"=>"create"
}
>> params["project"]["credit"]["creditable_type"]
=> "project"
👌 so I have that attribute but it's not inside the DB.
=> "ERROR: error param is missing or the value is empty: credit"
Hope that my question will help other junior dev to figure out the correct syntax to explore these nested form.
Upvotes: 2
Views: 163
Reputation: 331
Rails bug : Rails 5 polymorphic table requires optional: true
class ProjetsController < ApplicationController
...
def new
@projet = Projet.new
@projet.credits.build
# @creditable_type = "projet"
end
def create
@projet = Projet.new(projet_params)
if @projet.save
redirect_to @projet
else
render :new
end
end
...
end
<div class="form-inputs">
<%= f.simple_fields_for :credits do |credit_form| %>
<%= credit_form.input :category %>
<%= credit_form.input :content %>
<%= credit_form.input :link %>
<% end %>
...
</div>
class Projet < ApplicationRecord
has_many :credits, as: :creditable, dependent: :destroy
end
Upvotes: 1