Two different classes using accepts_nested_attributes of one class - ruby-on-rails

I have a class Addresse where Organismereferent and Organisme have a has_many belongs_to relationship with. Also Organismereferent and Organisme can accepts_nested_attributes_for :addresses
My problem is when I only had the Organismereferent class everything was working fine and I was able to create a new Organismereferent with an addresse but as soon as I created and added the same relation to Organisme , they both stopped working without giving any error message I only get this in the console:
My model:
class Organismereferent < ApplicationRecord
has_many :addresses
has_many :referents
accepts_nested_attributes_for :addresses
end
class Organisme < ApplicationRecord
has_many :addresses
accepts_nested_attributes_for :addresses
end
class Address < ApplicationRecord
belongs_to :organismereferent
belongs_to :organisme
end
Controller for Organisme
def new
#organisme = Organisme.new
#organisme.addresses.build
end
def create
#organisme = Organisme.new(organisme_params)
#organisme.status = true
#organisme.save
redirect_to #organisme
end
private
def organisme_params
params.require(:organisme).permit(:nom, :telephone, :courriel, :fax, addresses_attributes: [:id, :no_civique, :rue, :ville, :province, :etat, :code_postal])
end
Controller for Organismereferent:
def new
#organisme = Organismereferent.new
#organisme.addresses.build
end
def create
#organisme = Organismereferent.new(organisme_params)
#organisme.active = true
#organisme.save
redirect_to #organisme
end
private
def organisme_params
params.require(:organismereferent).permit(:nom_organisation, :bureau, :telecopie, :courriel, :site_web, addresses_attributes: [:id, :no_civique, :rue, :ville, :province, :etat, :code_postal])
end
I'm not sure what else information might be important so I'll be glad to add anything.

Try to change address model like
class Address < ApplicationRecord
belongs_to :organismereferent, optional: true
belongs_to :organisme, optional: true
end

Related

Rails , How to santize within the Model

I have the following model
Diary.rb
class Diary < ApplicationRecord
belongs_to :student
belongs_to :user
belongs_to :grade
has_many :diary_entries
validates :diary_year, presence: true
def self.from_student(owner, student_obj)
new(
user_id: owner.id,
student_id: student_obj.id,
grade_id: student_obj.grade_id,
#How to add diary_year here.....
)
end
end
My diary only had three attributes, user_id, grade_id, student_id... I added an extra attribute diary_year, the diary_year is a integer and I am not sure what is the right syntax to add it to the self.from_student..
My guess, but that fails.
diary_year: subject_obj.diary_year
Here is my controller
def create
#diary = Diary.from_student(current_user, #student)
#diary.save
redirect_to #student, notice: "Diary was successfully created."
end
You can populate the field with Date.today.year in the method:
class Diary < ApplicationRecord
belongs_to :student
belongs_to :user
belongs_to :grade
has_many :diary_entries
validates :diary_year, presence: true
def self.from_student(owner, student_obj)
new(
user_id: owner.id,
student_id: student_obj.id,
grade_id: student_obj.grade_id,
diary_year: Date.today.year #this populates the field automatically
)
end
end

Rails 5: Nested attributes aren't updated for model

I can't get rails to update my nested attributes, though regular attributes work fine. This is my structure:
unit.rb:
class Unit < ApplicationRecord
has_many :unit_skill_lists
has_many :skill_lists, through: :unit_skill_lists, inverse_of: :units, autosave: true
accepts_nested_attributes_for :skill_lists, reject_if: :all_blank, allow_destroy: true
end
unit_skill_list.rb:
class UnitSkillList < ApplicationRecord
belongs_to :unit
belongs_to :skill_list
end
skill_list.rb:
class SkillList < ApplicationRecord
has_many :unit_skill_lists
has_many :units, through: :unit_skill_lists, inverse_of: :skill_lists
end
And this is (part of) the controller:
class UnitsController < ApplicationController
def update
#unit = Unit.find(params[:id])
if #unit.update(unit_params)
redirect_to edit_unit_path(#unit), notice: "Unit updated"
else
redirect_to edit_unit_path(#unit), alert: "Unit update failed"
end
end
private
def unit_params
unit_params = params.require(:unit).permit(
...
skill_list_attributes: [:id, :name, :_destroy]
)
unit_params
end
end
The relevant rows in the form (using formtastic and cocoon):
<%= label_tag :skill_lists %>
<%= f.input :skill_lists, :as => :check_boxes, collection: SkillList.where(skill_list_type: :base), class: "inline" %>
Any idea where I'm going wrong? I have tried following all guides I could find but updating does nothing for the nested attributes.
Edit after help from Vasilisa:
This is the error when I try to update a Unit:
ActiveRecord::RecordInvalid (Validation failed: Database must exist):
This is the full unit_skill_list.rb:
class UnitSkillList < ApplicationRecord
belongs_to :unit
belongs_to :skill_list
belongs_to :database
end
There is no input field for "database". It is supposed to be set from a session variable when the unit is updated.
If you look at the server log you'll see something like skill_list_ids: [] in params hash. You don't need accepts_nested_attributes_for :skill_lists, since you don't create new SkillList on Unit create/update. Change permitted params to:
def unit_params
params.require(:unit).permit(
...
skill_list_ids: []
)
end
UPDATE
I think the best options here is to set optional parameter - belongs_to :database, optional: true. And update it in the controller manually.
def update
#unit = Unit.find(params[:id])
if #unit.update(unit_params)
#unit.skill_lists.update_all(database: session[:database])
redirect_to edit_unit_path(#unit), notice: "Unit updated"
else
redirect_to edit_unit_path(#unit), alert: "Unit update failed"
end
end

Active Model Serializer customize json response

So I'm having a problem with ams. I'm using Rails 5.2 and I read lots of tutorials and even when I did exactly what they showed I still have something that they don't and I didn't find answer on google.
I have model Course, Video, Quiz and Segment.
Course has many segment, segment can be video or quiz (I'm using sti).
This is how I wrote it:
app/models/course.rb
class Course < ApplicationRecord
validates :title ,presence: true
validates :author ,presence: true
has_many :videos
has_many :quizs
has_many :segments
end
app/models/segment.rb
class Segment < ApplicationRecord
belongs_to :course
end
app/models/quiz.rb
class Quiz < Segment
validates :course_id ,presence: true
validates :name ,presence: true
belongs_to :course
end
app/models/video.rb
class Video < Segment
validates :course_id ,presence: true
validates :name ,presence: true
belongs_to :course
end
app/controllers/courses_controller.rb
class CoursesController < InheritedResources::Base
def show
#course = Course.find(params[:id])
render json: #course.attributes
end
def index
#courses = Course.all
render json: #courses
end
end
app/serializers/course_serializer.rb
class CourseSerializer < ActiveModel::Serializer
attributes :title, :author
has_many :segments
end
and this is what is showed me
I have couple of problems:
I don't know where this data name come from and I don't know how to change it or hide it.
even when I request to see one course I get the created date and other stuff I didn't want, although I configured it so I only see title and author.
I want to know if I can custom the json response so I won't see the title of the relations or change it's name.
You haven't created a SegmentSerializer. By default, AMS will serialize all fields.
class SegmentSerializer < ActiveModel::Serializer
attributes :name
end
Remove the attributes method call. It returns a Hash and then your serializer is not used.
```
class CoursesController < InheritedResources::Base
def show
#course = Course.find(params[:id])
render json: #course
end
def index
#courses = Course.all
render json: #courses
end
end
```
Use the key option
has_many :segments, key: :your_key

Rails Model doesn't save data with polymorphic

I have a model job and a model user, the both can choose contracts types (that's why i use polymorphic).
I created a model contract for each contracts and i create an attached_contract model too.
Job model
class Job < ApplicationRecord
has_many :contracts, through: :attached_contracts
has_many :attached_contracts, as: :contractable, dependent: :destroy
accepts_nested_attributes_for :attached_contracts, reject_if: :all_blank, allow_destroy: true
end
AttachedContract model
class AttachedContract < ApplicationRecord
belongs_to :contract
belongs_to :contractable, polymorphic: true
validates :contract, uniqueness: { scope: [:contractable_type,:contractable_id] }
end
Contract model
class Contract < ApplicationRecord
validates :name, presence: true, allow_blank: false
has_many :attached_contracts
end
Jobs_controller
def new
#job = Job.new
#job.attached_contracts.build
end
def create
#job = current_company.jobs.build(set_params)
if #job.save
redirect_to job_path(#job)
end
else
render :new
end
end
def set_params
params.require(:job).permit(:title, :description, :address, attached_contracts_attributes: [:id, :contract_id, :_destroy]
end
In my view :
<%= simple_form_for([:company, #job]) do |f| %>
<div class="nested-fields">
<%= f.association :contracts, as: :check_boxes %>
</div>
<% end %>
When I submit my form my model AttachedContract still empty, and the data are lost.
I try tu put a "raise" in my controller after #job = current_company.jobs.build(set_params)
and I have a empty array if I call #job.attached_contracts
I don't understand beause in the "Request parameters" (rails debug console) I have the values : "contract_ids"=>["", "1", "3"]
Any idea ? May be the problem is in the polymorphic implantation ?
Finally, I changed the requested parameters by "contract_ids: [ ]" and that's work perfectly !

Undefined Method when .build new Object

I'm new to Ruby on Rails and currently trying to make a little test website for me.I've got an issue in my code that states an "undefined method `service_providers' for #"
The line of code which produces the error is the following:
def new
#service_provider = current_user.service_providers.build(serviceprovider_params)
end
My Database Model is Table "User" has_one "ServiceProvider" has_many "Services".
I use the rubygem "devise" for the user-model.
I've tried to transfer the idea of the micropost of the "Ruby on Rails Tutorial" (https://www.railstutorial.org/book/user_microposts) in my example app. In Listing 13.36 there's also this code because with this ruby knows the reference between the current_user and the micrrpost.
I don't have an idea why it isn't working with my code:
Model
class ServiceProvider < ApplicationRecord
belongs_to :user
has_many :service
validates :name, presence: true
validates :street, presence: true
validates :plz, presence: true
validates :location, presence: true
validates :user_id, presence: true
end
Controller
class ServiceProvidersController < ApplicationController
before_action :set_serviceprovider, only: [:show, :edit, :update]
before_action :authenticate_user!
def index
end
def show
end
def new
#service_provider = current_user.service_providers.build(serviceprovider_params)
end
def create
#service_provider = current_user.service_provider.build(serviceprovider_params)
if #service_provider.save
redirect_to #service_provider, notice: "Gespeichert"
else
render :new
end
end
def edit
end
def update
end
private
def set_serviceprovider
#service_provider = Service_Provider.find(params [:id])
end
def serviceprovider_params
params.require(:service_provider).permit(:name, :street, :plz, :location)
end
end
ServiceProvider-Helper
module ServiceProvidersHelper
def current_service_provider
#current_service_provider = service_provider.user_id.find(current_user.id)
end
end
If there's some coding missing which you need for your help, please ask. I'm a newbie in coding with ruby, but i think taht must be the relevant parts of the code which is involved.
Thanks for help.
If you have has_one association then you need to use build_ASSOCIATION_NAME so in this case, it will be build_service_provider
#service_provider = current_user.build_service_provider(serviceprovider_params)
Also, I think you need to take a look at this association
class ServiceProvider < ApplicationRecord
belongs_to :user
has_many :service
If you are building an association with has_many then the class name should be plural.
Change it to
has_many :services

Resources