Naming error in controller
I get this error when trying to create a record in my joins table
NameError in SubscriptionsController#new
uninitialized constant Channel::ChannelsUser
Subscriptions Controller
class SubscriptionsController < ApplicationController
helper_method :current_user_session, :current_user
filter_parameter_logging :password, :password_confirmation
def new
@channel = Channel.find(params[:channel_id])
@user = current_user
@channel.subscribers << @user
@channel.save
flash[:notice] = "You have subscribed to: " +@channel.name
redirect_to @channel
end
end
end
User Model
class User < ActiveRecord::Base
acts_as_authentic
ROLES = %w[admin moderator subscriber]
#Each user can subscribe to many channels
has_many :channels_users
has_many :subscriptions, :class_name => "Channel", :through => :channels_users
#Each user who is a moderator can moderate many channels
has_many :channel_mods
has_many :channels, :through => :channel_mods
#Each user can receive many messages
has_ma开发者_如何学运维ny :messages_users , :dependent => :destroy
has_many :reciepts , :class_name => "User", :through => :messages_users
#Filter users by role(s)
named_scope :with_role, lambda { |role| {:conditions => "roles_mask & #{2**ROLES.index(role.to_s)} > 0 "} }
def roles
ROLES.reject { |r| ((roles_mask || 0) & 2**ROLES.index(r)).zero? }
end
def roles=(roles)
self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.sum
end
def role_symbols
role.map do |role|
role.name.underscore.to_sym
end
end
end
Channel Model
class Channel < ActiveRecord::Base
#Each channel owns many or no messages
has_many :messages
#Each channel is own by one moderator
has_many :channel_mods
has_many :moderators, :class_name =>'User', :through =>:channel_mod
#Each channel can have and belong to many or no users
has_many :channels_users
has_many :subscribers, :class_name => 'Users' , :through => :channels_users
end
ChannelsUsers model
class ChannelsUsers < ActiveRecord::Base
belongs_to :user
belongs_to :channel
end
This would read much nicer if you change the model to ChannelUser. Here are the corresponding relationships:
class Channel < ActiveRecord::Base
has_many :channel_users
has_many :users, :through => :channel_users
end
class User < ActiveRecord::Base
has_many :channel_users
has_many :channels, :through => :channel_users
end
class ChannelUser < ActiveRecord::Base
belongs_to :channel
belongs_to :user
end
Your join table would then be called channel_users
. I think you named it channels_users
initially because that's the setup for a has_and_belongs_to_many join table. But since you're using has_many :through
, you're free to name the table as you like.
I wrote a blog article earlier this year that walks through all the options in detail:
Basic Many-to-Many Associations in Rails
I hope this helps!
Your channel user class name is a plural. It is supposed to be singular.
So either you can change to this:
class ChannelsUser < ActiveRecord::Base
belongs_to :user
belongs_to :channel
end
or change this line in User
and Channel
model:
has_many :channels_users
to
has_many :channels_users, :class_name => 'ChannelsUsers'
Rails will use the methods like String#classify
and String#underscore
to detect classes and relationships.
If you want to play around with the names, in the console try out various combinations:
>> "channels_users".classify
=> "ChannelsUser"
>> "ChannelsUser".underscore
=> "channels_user"
精彩评论