Retrieve method for a polymorphic, has_one and scoped association - ruby-on-rails-4

Hi this is somewhat it trivial but I can't for the life of me figure out where to make the adjustments.
I have a LoanApplication model and a transfer model like this:
class LoanApplication < ActiveRecord::Base
before_save :populate_guid
belongs_to :user
has_one :loan, -> { where loan: true }, as: :transferable
has_one :repayment, -> { where repayment: true }, as: :transferable
validates_uniqueness_of :guid
private
def populate_guid
if new_record?
while !valid? || self.guid.nil?
self.guid = SecureRandom.random_number(1_000_000_000).to_s(36)
end
end
end
end
and
class Transfer < ActiveRecord::Base
belongs_to :transferable, polymorphic: true
belongs_to :user
validates_presence_of :transferable_id,
:transferable_type,
:user_id,
:amount,
:password
end
How come LoanApplication.first.loan gives me the following error message
LoanApplication Load (1.1ms) SELECT "loan_applications".* FROM "loan_applications" ORDER BY "loan_applications"."id" ASC LIMIT 1
NameError: uninitialized constant LoanApplication::Loan
All insights appreciated.
Thanks

I think Application is a reserved word. Try to rename LoanApplication?

It was trivial, I just needed to add class_name: "Transfer" for everything to work. -__-'

Related

passing parameter in has_many through association

I have a class Test, Question, Testquestion associated by has_many through
class Test
has_many :testquestions
has_many :questions, through: :testquestions
end
class Question
has_many :testquestions
has_many :tests, through: :testquestions
end
class Testquestion
belongs_to :test
belongs_to :questions
end
While creating a Test i want to pass a value of column order of Testquestion.
def create
Test.create(test_params)
end
def test_params
params.require(:test).permit(:testname,question_attributes:[:questionname])
end
How should i pass value of order column so that associated model(Testquestion) get updated.
There's no way to do it that way, you will need to take a longer path.
Don't forget to add accepts_nested_attributes_for to your assossiations, so that nested operations would actualy work.
Check that you have added accepts_nested_attributes_for :question to Testquestion.
Get your params structured right.
Something like this:
{
test: {
testname: 'someName',
testquestion_attributes: {
order: someOrder,
question_attributes: {
questionname: 'someName'
}
}
}
}
Require your params.
params.require(:test).permit(:testname, testquestion_params: [:id, :order, :_destroy, question_params: [:id, :questionname])
p.s. sidenote: you should really aquire a habbit of naming your fields and variables in snake_case and your classes in CamelCase.

rails 4 - associations - is it possible to have a polymorphic association on one side of a many-through?

I have a Has-Many:Through association , in which one side (AccessLevel ) is a defined model 'AccessLevel' , but the other side can be set for multiple resources
I defined a specific concern to be included in these models, and tried to use a polymorphic association
class AccessLevel < ActiveRecord::Base
has_many :allowed_activities
has_many :actionable, through: :allowed_activities
end
class AllowedActivity < ActiveRecord::Base
belongs_to :access_level
belongs_to :actionable, polymorphic: true
end
class <Model> < ActiveRecord::Base
include Authorizable
end
module Authorizable
extend ActiveSupport::Concern
included do
has_many :allowed_activities, as: :actionable
has_many :access_levels, through: :allowed_activities
end
end
is that a correct implementation or am I going to raise some unexpected collateral issues ?
thanks for feedback
It's not possible to use has_many: :through on polymorphic object
I need to specify the source_type of each object ( Sheet, ...
has_many :actionable_sheets, :through => :allowed_activities, :source => :actionable, :source_type => 'Sheet'

Rails & nested comments through partials, strange recursion

I've got a pretty simple setting for (polymorphic) comments model which also have a has_many relationship wih itself (called :replies):
# comment.rb
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
default_scope -> { order(created_at: :asc) }
belongs_to :user
belongs_to :comment_parent, class_name: "Comment", foreign_key: "comment_id"
has_many :replies, class_name: "Comment", foreign_key: "comment_id"
validates :content, presence: true
validates :commentable, presence: true
end
In the post controller I fetch the comments:
#comments = #commentable.comments.all()
I'm initiating the partial on my blog view page like so:
= render #comments
And finally the comment/_comment partial containing:
(simpiflied code, this only shows gravatar & username)
# comment/_comment.html.haml
%ol.media-list
%li.media{:class => ("media-replied" if comment.comment_id)}
= link_to gravatar_for(comment.user, size: 80, class_name: 'media-object img-circle'), comment.user, class: 'pull-left'
= render partial: 'comments/comment', collection: comment.replies
Somehow this creates some strange recurrence, in which replies get shown on their correct location, but also on an incorrect location. Problem is that there doesn't seem to be any logic in this. (at least for me it doesn't)
I've checked console to verify that the database contains the correct relations between the records (no faulty records), so it must be in the presentation / partial call.
Any ideas?
Ok, that was my own stupid mistake of course... the call #commentable.comments.all() result is all the comments, so even the nested comments are shown as if they are top level.
Short term fixed it by adding where(comment_id: nil)

Rails 4 - has_many through fetching issue

I have a many to many association wich is being implemented with rails has_many through shortcut.
My models are called:
Cliente
StatusTransacaoPagSeguro
Historico
They were defined this way:
class StatusTransacaoPagSeguro < ActiveRecord::Base
has_many :historicos
has_many :clientes, through: :historicos
end
class Cliente < ActiveRecord::Base
has_many :historicos
has_many :status_transacao_pag_seguros, through: :historicos
end
class Historico < ActiveRecord::Base
belongs_to :cliente
belongs_to :status_transacao_pag_seguro
end
I have the following historico record:
#<Historico id: 1, cliente_id: 3, status_transacao_pag_seguros_id: 3, created_at: "2014-06-01 19:44:42", updated_at: "2014-06-01 19:44:42">
when I run
historico.cliente
I get the associated 'cliente' record, but when I run
historico.status_transacao_pag_seguro
I get nil.
Where's the problem? I defined the pluralization correctly? Since those names are in Portuguese language I think that there's some problem with it but I don't know how to overcome that.
Your FK for status_transacao_pag_seguro in historicos table is wrong. It should be status_transacao_pag_seguro_id (without the s). With the following migration you should be good to go:
def change
rename_column :historicos, :status_transacao_pag_seguros_id, :status_transacao_pag_seguro_id
end

Rails - Multiple Nested Attributes

I am trying to use a select tag to save multiple nested children in a parent.
This is the error I'm looking at
Couldn't find all UserLocations with IDs (1, 2) (found 0 results, but was looking for 2)
I have the following setup under Rails 4 and Devise:
User
class User < ActiveRecord::Base
has_many :user_locations
accepts_nested_attributes_for :user_locations, :allow_destroy => true
end
UserLocation (locations that the user has)
class UserLocation < ActiveRecord::Base
belongs_to :user
belongs_to :location
end
Location (predefined list of locations the user can choose upon)
class Location < ActiveRecord::Base
has_many :user_locations
has_many :users, through: :user_locations
end
However, when trying to save the selected UserLocations, they won't be saved.
Rails Select Tag (You can choose multiple items)
<%= f.select :user_location_ids, options_for_select(Location.all.collect { |l| [ l.name, l.id ] }, #user.user_locations.collect{ |l| l.id }), {}, { multiple: true } %>
I have put the user_location_ids in my application_controller as user_location_ids: []
Cheers
Solved
The solution is to overwrite the default setter method for multiple nested models model_ids=(value). Do not use the plural of the model, e.g. models_ids=(value), because that is wrong!
def user_location_ids=(value)
for slot in value do
unless slot == ""
location = Location.find_by(id: slot.to_i)
unless location.nil?
self.user_locations << UserLocation.create(user_id: self.id, location_id: location.id)
end
end
end
end