Reputation: 1608
I'm running into an issue with an associated model. I have a nested attributes for my user, to a reviewer. A user can essentially review another person, thus be a reviewer and be the person reviewed.
It's set up like this:
# User
has_many :reviewers
accepts_nested_attributes_for :reviewers
has_many :active_managements, class_name: 'Reviewer',
foreign_key: 'reviewer_id',
dependent: :destroy
class Reviewer < ActiveRecord::Base
belongs_to :user
belongs_to :reviewer_id, class_name: 'User'
end
now in my users controller I have:
class UsersController < ApplicationController
def edit
@user = User.find(params[:id])
@user.reviewers.build
redirect_to root_url && return unless @user.activated?
end
def update
@user = User.find(params[:id])
if @user.update_attributes(user_params)
redirect_to edit_user_path(@user)
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:invitation_token, :first_name, :admin,
:last_name, :title, :email, :password,
reviewers_attributes: [:reviewer_id])
end
the error that I get is:
User(#70197180889680) expected, got String(#70197172430700)
happening on "user_params", so I assume it has to do with my attributes. Anybody know what's up?
Upvotes: 1
Views: 1283
Reputation: 76784
The immediate fix is here:
#app/models/review.rb
class Reviewer < ActiveRecord::Base
belongs_to :reviewer
end
--
This is how I'd fix the systemic issue:
#config/routes.rb
resources :users do
resources :reviewers #-> url.com/users/:user_id/reviews/new
end
#app/controllers/reviewers_controller.rb
class ReviewersController < ApplicationController
def new
@user = User.find params[:user_id]
@review = user.reviewers.new
end
def create
@user = User.find params[:user_id]
@review = user.reviewers.new reviewer_params
end
private
def review_params
params.require(:reviewer).permit(:user_id, :reviewer_id)
end
end
Models
Apart from this, I think your main issue is the way your models are set up.
Ideally, you want to have reviewer
and user
as the same data-set (I presume they're both users
), which makes your current setup really inefficient...
#app/models/user.rb
class User < ActiveRecord::Base
has_and_belongs_to_many :reviewers,
class_name: "User",
join_table: :reviewers_users
foreign_key: :user_id,
association_foreign_key: :reviewer_id
end
What you're looking for is something called a self referrential association, which basically allows you to associate the same model in a many-to-many
relationship.
In most cases, this will be used with a has_and_belongs_to_many
relationship; you could also use a has_many :through
although it's not as common.
The above will allow you to use the following:
@user = User.find params[:id]
@user.reviewers #-> collection of users who are reviewers of original user
Upvotes: 1
Reputation: 1567
The line belongs_to :reviewer_id, class_name: 'User'
is incorrect. Try changing it to something like belongs_to :reviewing_user, class_name: 'User'
(replacing reviewing_user
with whatever name you want to use for this association :), not field name.
http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/belongs_to
Upvotes: 3