ParameterMissing: param is missing or the value is empty: apartment_param - ruby-on-rails-5

I am trying to submit a "create" method on an apartment model, which returns exception:
rake routes:
POST /api/v1/owners/:owner_id/apartments(.:format) api/v1/apartments#create {:format=>"json"}
I have created an API for owners & apartments:
owner.rb
class Owner < ApplicationRecord
has_many :apartments
#Validations
validates_presence_of :name, :email, :password_digest
validates :email, uniqueness: true
#encrypt password
has_secure_password
end
apartment.rb
class Apartment < ApplicationRecord
has_one :owner
end
getting an error while submitting request with postman with all permitted params.
{
"status": 400,
"error": "Bad Request",
"exception": "#<ActionController::ParameterMissing: param is missing or
the value is empty: apartment>"
...
..

Error is from part of your controller & view & not model. From view, params are passed where it does not include apartment key.
And you are looking for params[:apartment] in controller code.

Had to remove the require, since I don't use a "new" form. And also add an owner_Id permit. Works as expected now.

Related

Rails: Scope parent model by attribute of child

I'm having a tough time figuring something out in Rails. It probably has to do with my very limited knowledge of SQL, since I know Rails pretty well. I'm using Rails 5.
I have two models: Applicant and Application.
class Applicant < ApplicationRecord
has_one :application
has_many :skills
accepts_nested_attributes_for :application
accepts_nested_attributes_for :skills,
reject_if: ->(skill) { skill[:name].empty? || skill[:experience].empty? }
validates_with ApplicantValidator
end
class Application < ApplicationRecord
belongs_to :applicant
has_many :notes
VALID_STATUSES = ["in review", "accepted", "declined", "closed"]
validates_length_of :why_interested, minimum: 25
validates :accept_terms, acceptance: true
validates :status, inclusion: { in: VALID_STATUSES }
before_validation :set_status
private
def set_status
self.status ||= "in review"
end
end
I'd like to add a scope, :active, to the Applicant model that returns only applicants who have an application whose status is "in review". However, I can't find a way to access the application within a scope proc.
I've seen other suggestions for cases where there is a has_many relationship with the child, but they didn't work in my case.
I doubt it makes a difference, but I'm using Postgres. The closest I've come to a solution is to add this, but when I run RSpec it says there needs to be a FROM-clause for the applications table. I don't know how to effect that.
scope :active, -> { joins(:application).where('"application"."status" = "in review"') }
scope :in_review_applicants, -> { joins(:application).where('application.status = ?', :in_review) }
I think is something like that..

Restore recursive does not restore entries in join table

Setup
class Profile < ApplicationRecord
acts_as_paranoid
has_many :degreeholderships
has_many :degrees, through: :degreeholderships, dependent: :destroy
end
class Degreeholdership < ApplicationRecord
acts_as_paranoid column: :active, sentinel_value: true
belongs_to :profile
belongs_to :degree
validates :profile_id, presence: true
validates :degree_id, presence: true
def paranoia_restore_attributes
{
deleted_at: nil,
active: true
}
end
def paranoia_destroy_attributes
{
deleted_at: current_time_from_proper_timezone,
active: nil
}
end
end
class Degree < ApplicationRecord
has_many :degreeholderships
has_many :profiles, through: :degreeholderships, dependent: :destroy
end
Steps to reproduce:
call destroy method on profile.
entries in degreeholderships table are marked active=NULL and have deleted_at=timestamp
call restore method on profile and pass recursive: true
profile.restore(recursive: true)
entries in degreeholderships table stay the same
Expected outcome:
entries in degreeholderships that were associated with profile should be restored as well.
I have attempted to run restore with and without the recursive: true option as well as set the recovery_window value. All display this behavior. I have also removed the option to use the active column and revert back to using deleted_at (the default).
I'm looking to understand whether this behavior is:
Due to an error in my setup.
Actually the expected behavior and if so please explain why this is preferred over being able to restore the dependents recursively.
Is a bug with the gem.
Parameters: {"type"=>"restore", "id"=>"18"}
Pt Load (0.6ms) SELECT "pts".* FROM "pts" WHERE "pts"."deleted_at" IS NULL AND "pts"."id" = $1 LIMIT $2 [["id", 18], ["LIMIT", 1]]
overriding default queries works for all methods except destroy, really destroy, and restore
Completed 401 Unauthorized in 9ms (ActiveRecord: 1.3ms)
ActiveRecord::RecordNotFound (Couldn't find Product with 'id'=18 [WHERE "pts"."deleted_at" IS NULL]):
This is a simple 1 table with no associations ?

How to validate uniqueness of nested models in the scope of their parent model in Rails 3.2?

Here is an example of my problem.
I have a 'Room' model:
class Room < ActiveRecord::Base
has_many :items, :inverse_of => :room
accepts_nested_attributes_for :items
end
And I have an 'Item' model:
class Item < ActiveRecord::Base
belongs_to :room, :inverse_of => :items
validates :some_attr, :uniqueness => { :scope => :room}
end
I want to validate the uniqueness of the :some_attr attribute of all the Items which belongs to a certain room.
When I try to validate the items, I get this error:
TypeError (Cannot visit Room)
I cannot set the scope of the validation to be :room_id since the items are not saved yet so the id is nil. I also want to prevent using custom validators in the 'Room' model.
Is there any clean way to do it in Rails? I also wonder if I set the :inverse_of option correctly...
I don't see anything wrong with how you're using inverse_of.
As for the problem, in a similar situation I ended up forcing a uniqueness constraint in a migration, like so
add_index :items, [ :room_id, :some_attr ], :unique => true
This is in addition to the AR-level validation
validates_uniqueness_of :some_attr, :scope => :room_id
(I'm not sure if it's valid to use the association name as a scope, won't the DB adapter raise an exception when trying to refer to the non-existent room column in a query?)

Rails: Need help with nested form rejecting nested object but still creating main object

I have the following in my user model
class User < ActiveRecord::Base
has_many :gym_users
attr_accessible :gym_users_attributes, :gym_users
accepts_nested_attributes_for :gym_users, :reject_if => lambda { |a| a[:role_id].blank? }
end
This correctly rejects the gym_user model if the role_id is not present, the problem is it still creates the user and simply doesn'
t create the gym_user. Is there a way to make it not create or delete the user when the gym_user is rejected?
You can add
validates_associated :gym_users
to your User model and move validation from reject_if to GymUsers model
validates_presence_of :role_id
Add validates :gym_users, :presence => true to your User model

validates :presence vs validates_presence_of using rails 3

I have a couple of simple models that are associated like so:
MODELS
class Task < ActiveRecord::Base
belongs_to :user
validates :name, :presence => true, :message => 'Name cannot be blank, Task not saved'
end
class User < ActiveRecord::Base
has_many :tasks
end
VIEW has a call in it like so:
user.tasks <-- then I loop through the tasks
The Issue:
In the task model --
when I use:
validates :name, :presence => true , :message => 'Name cannot be blank, Task not saved'
I get a 500 error:
ActionView::Template::Error (uninitialized constant User::Task):
NameError in View file
when I use:
validates_presence_of :name
Everything works.
I thought the both validates methods above where the same...is the issue have to do with associations and how validation tie into associated models. I have a hunch that something is going on with the way things are associated, but it is just a hunch.
Any help will be appreciated. Thank very much.
When you use the newer validates :name format, you can put multiple validations in one line rather than having to have multiple lines for each type of validation. Because of this, when Rails hits your :message parameter, it thinks it's a validation method rather than a message associated with :presence. Try this instead:
validates :name, :presence => {:message => 'Name cannot be blank, Task not saved'}
Also, depending on how you display your errors, this error may actually show up as 'Name Name cannot be....'; if so, you'll want to set the message to just 'cannot be blank, Task not saved'.