Error with Hanami has_many associations (in 1.1.0.beta1) - hanami

I am using Hanami 1.1.0.beta1 (because I need associations).
An event can have many actions:
class EventRepository < Hanami::Repository
associations do
has_many :actions
...
end
class ActionRepository < Hanami::Repository
associations do
...
belongs_to :event
end
When I call this EventRepository method:
def add_action(event, data)
assoc(:actions, event).add(data)
end
I get this error:
KeyError:
key not found: :id
# /home/eric/.gem/ruby/2.3.4/gems/hanami-model-1.1.0.beta1/lib/hanami/model/associations/has_many.rb:195:in `fetch'
# /home/eric/.gem/ruby/2.3.4/gems/hanami-model-1.1.0.beta1/lib/hanami/model/associations/has_many.rb:195:in `_build_scope'
# /home/eric/.gem/ruby/2.3.4/gems/hanami-model-1.1.0.beta1/lib/hanami/model/associations/has_many.rb:47:in `initialize'
# /home/eric/.gem/ruby/2.3.4/gems/hanami-model-1.1.0.beta1/lib/hanami/model/association.rb:20:in `new'
# /home/eric/.gem/ruby/2.3.4/gems/hanami-model-1.1.0.beta1/lib/hanami/model/association.rb:20:in `build'
# /home/eric/.gem/ruby/2.3.4/gems/hanami-model-1.1.0.beta1/lib/hanami/repository.rb:472:in `assoc'
...
I looked in has_many.rb. In initialize I see that subject is an Event object and it has an id:
HasMany::initialize - subject: #<Event:0x00558f3c198ce8 #id=705,
#attributes={:title=>"test_title"}>
but in _build_scope subject has changed to be just the attributes hash, hence the key not found: :id error.
HasMany::_build_scope - subject: {:title=>"test_title"}
which is weird because I don't see any place where subject is changed between initialize and _build_scope...
So is this a bug is 1.1.0.beta1, or am I doing something wrong?

Related

Rails 5 - Mongoid - Concerns

I'm trying to abstract generic functions to a model concern on a Rails 5 with Mongoid app. This is the first app I do with mongoid and with other projects I had no problems implementing the next:
movie.rb
class Movie
include Mongoid::Document
include Genericable
field :name, type: String
field :year, type: Date
field :length, type: Integer
field :writers, type: Array
validates_presence_of :name, :year, :length
validates_uniqueness_of :name
index({name: 1}, {unique: true})
has_many :writers, class_name: "Person"
embeds_many :roles, class_name: "MovieRole"
end
genericable.rb (concern)
module Genericable
extend ActiveSupport::Concern
def self.s
all.map{|x| x}
end
end
(Methods are for demonstration purposes only).
When I try, on my rails console Movie.s I get next error:
NoMethodError: undefined method `s' for Movie:Class
Any clue about what I'm doing wrong? Thanks in advance for any help.

Delete a Post without the associated Task

I would like to be able to destroy my Post without the Task which is associated. But I'm currently facing a SQL error which say:
ActiveRecord::InvalidForeignKey (SQLite3::ConstraintException: FOREIGN KEY constraint failed: DELETE FROM "posts" WHERE "posts"."id" = ?):
After a few search, I saw that is coming from associations and Foreign Key. But I cannot solve the problem for the moment.
I have tested to put (optional: true) into my model.
I also have tried to change the foreign key into (, on_delete: :cascade) & (, on_delete: :nullify) but it's still not working.
My code =
//Post Model
class Post < ApplicationRecord
has_one :task
end
//Task Model
class Task < ApplicationRecord
belongs_to :post, optional: true
end
To destroy :
//Destroy_one into the Post Controller
def destoy_one
#post.destroy
end
Migration File : (also tried with on_delete: :nullify)
class EditForeightKeys < ActiveRecord::Migration[5.1]
def change
# remove the old foreign_key
remove_foreign_key :tasks, :post
# add the new foreign_key
add_foreign_key :tasks, :post, on_delete: :cascade
end
end
Do you have any other solution for that ?
I solve this issue by implement a deleted_state into Posts
def destroy_one
#post.update(deleted_state: true)
end
And after you can put a default scope into your Post model like this :
default_scope { where(deleted_state: false) }
Like this all will work without problems !!
You can use callbacks on destroy action for User as a variant:
class Post
before_destroy :update_tasks
private
def update_tasks
self.tasks.update_all(post_id: nil)
end
end

Rails 3 superclass mismatch for class Location

I'm running Rails 3.2.13 and Ruby 2.1.0.
This error has popped up in a seemingly random fashion. I only have one Location class in my app. But I did add several new gems recently: Rmagick, CarrierWave and CarrierWave-Azure.
Here's the error:
TypeError in CompaniesController#show
superclass mismatch for class Location
app/models/location.rb:1:in `<top (required)>'
app/controllers/companies_controller.rb:24:in `show'
If I go to companies_controller.rb ln 24 there is this code:
#addresses = #company.addresses
Line 23: actually references Location:
#locations = #company.locations
If I step through the code in debug mode the #locations variable isn't created anymore when line 23 executes, all other variables prior to line 23 are created. I haven't touched this code in months, the only recent additions to the codebase have revolved around the gems I listed above but did not include changes to Location.rb, Company.rb, Address.rb or Companies_Controller.
Anyone know what's going on here? thx!
Update:
Here is my Location model:
class Location < ActiveRecord::Base
attr_accessible :address_attributes, :address, :created_by, :is_active, :location_name, :location_type_id,
:region_id, :updated_by, :website
# set schema name and table name for TakebackDBMS
self.table_name ="recycle.Location"
# define associations
has_many :companyContacts
belongs_to :location_type
belongs_to :company
belongs_to :address
belongs_to :region
default_scope order: 'location_name' # return locations list in Alphabetical order
accepts_nested_attributes_for :address, :reject_if => :all_blank
#validations
validates :location_name, presence: true, length: { maximum: 100 }
validates :created_by, length: { maximum: 50 }
end
Looks like one of your gems/plugins already defines a Location Class.So is the error.
To resolve this,you should be changing your Location class in your app to some name like Location1
class Location1 < ActiveRecord::Base
This should solve your problem.And don't forget to change your Model file name to location1.rb

Accessing Rails Helper files from models

I am trying to validate the input of a state field using:
include ActionView::Helpers
class Credentials < ActiveRecord::Base
attr_accessible :license_number, ...:address_zip_code,
...
validates :license_number, presence: true, length: { minimum: 4 }
...
validates_inclusion_of :current_practice_address_state, :in => state_list
end
The variable state_list is an array described in helpers/credentials_helper.rb
Testing the model I run into undefined local variable error
$ bundle exec rspec spec/models/credentials_spec.rb
in `method_missing': undefined local variable or method `state_list' for #<Class:0x007f86a1844250> (NameError)
The helper class looks like:
module CredentialsHelper
state_list = %w(AL AK...WY)
end
Your call to include has to be inside the class:
class Credentials < ActiveRecord::Base
include ActionView::Helpers
...
end

Writing arbitrary attributes on a model is deprecated. (Multiple belongs_to on model)

I have multiple belongs_to relationships to the same model. Modeling messages between two users as follows (in the Message model):
belongs_to :to, :class_name => 'User', :foreign_key => 'to_id'
belongs_to :from, :class_name => 'User', :foreign_key => 'from_id'
attr_accessible :to, :from # ...
The corresponding has_many calls are in the User model. Everything works in the spec and the console as I need it to, with the exception of the following deprecation warning (for both from_id and to_id):
DEPRECATION WARNING: You're trying to create an attribute `from_id'. Writing arbitrary attributes on a model is deprecated. Please just use `attr_writer`
The relevant spec follows:
it "can associate users" do
User.delete(:all)
ufrom = FactoryGirl.create(:DrKevorkian)
ufrom.save!
uto = FactoryGirl.create(:JohnSmith)
uto.save!
m = Message.new
m.from = ufrom # <-- Warning here
m.to = uto # <-- Warning here
m.save
m.from.id.should == ufrom.id
m.to.id.should == uto.id
end
It seems to me the warning is happening as a result of the belongs_to association -- is there a cleaner/better way to do this?
Thanks very much.
My experience is that you get this warning if you forgot to run rake db:migrate and rake db:test:prepare after changing your schema.