I'm implementing my own user messaging feature in my application, but I'm having difficulty retaining the receiver_id.
User model:
class User < ActiveRecord::Base
has_many :tickets
has_many :sent_messages, :class_name => 'Message', :foreign_key => 'sender_id', :dependent => :destroy
has_many :received_messages, :class_name => 'Message', :foreign_key => 'receiver_id', :dependent => :destroy
end
Message model:
class Message < ActiveRecord::Base
belongs_to :sender, :class_name => 'User', :foreign_key => 'sender_id'
belongs_to :receiver, :class_name => 'User', :foreign_key => 'receiver_id'
end
Message controller:
def new
#user = User.find( params[:user_id] )
#message = Message.new(
:receiver => #user )
end
def create
#message = current_user.sent_messages.create( params[:message] )
redirect_to( tickets_path, :message => 'Message has been sent.' )
end
receiver_id in the db remains null.
Thanks for the help!
EDIT
Routes question here - ticket has users that can send messages - rails messaging
HTTP is stateless, so each request knows nothing about the one(s) before it. Thus, setting an attribute when calling Message.new in the controller doesn't carry over to the create request on its own—you need to have a hidden form field containing it. Assuming you're using form_for, it would be something like so:
<%= f.hidden_field :receiver_id %>
Related
i'm breaking my head to get the user of this situation:
a conversation model:
has_many :conversation_participants, :dependent => :destroy
has_many :users,
:through => :conversation_participants
has_many :messages, :dependent => :destroy
has_one :display_message,
:class_name => 'Message',
:order => 'created_at DESC'
def participants(options={})
if options[:not].is_a? User
users - [options[:not]]
else
users
end
end
and conversation_participants:
belongs_to :user
belongs_to :conversation
attr_accessible :user_id
on a conversation helper:
def self_or_other
#conversation.conversation_participants.find_by_user_id(:not => current_user)
end
please, someone could clear me how to get the other user inside conversation_participants model?
I believe like follows:
#conversation.conversation_participants.where.not(user_id: current_user.id).first
I don't understand why I get the following error:
ActiveRecord::AssociationTypeMismatch: User(#29943560) expected, got Fixnum
when I do that in rails console: #game = Game.create(:player => 1060, :played => 1061)
I just want to create a new Game regarding model associations below.
class User < ActiveRecord::Base
has_many :game_as_player, :class_name => 'Game', :foreign_key => 'player_id'
has_many :game_as_played, :class_name => 'Game', :foreign_key => 'played_id'
end
class Game < ActiveRecord::Base
belongs_to :player, :class_name => 'User'
belongs_to :played, :class_name => 'User'
attr_accessible :player, :played, :score, :details, :viewed, :read
end
If anyone has an idea...
Thanks a lot!
It just says that it want a User and you give a Fixnum
You should do something like
#game = Game.create(:player => Player.find(1060), :played => Player.find(1061))
Or, if you want to give the users by ids
#game = Game.create(:player_id => 1060, :played_id => 1061)
So basically, my app contains users (model User) who have friends (unilateral access), and who also own lists.
What I'm trying to achieve here is when creating a new list, to provide it with "accessors", picked from the user's friends.
My code is heavily inspired from the following railscast on virtual attributes.
So, here comes my User and UserAccessor model (just the relevant parts) :
class User < ActiveRecord::Base
has_many :lists, :dependent => :destroy
has_many :friendships, :dependent => :destroy
has_many :friends, :through => :friendships
end
class UserAccessor < ActiveRecord::Base
belongs_to :accessor, :class_name => "User"
belongs_to :accessible_list, :class_name => "List"
end
My List model :
class List < ActiveRecord::Base
has_many :items
belongs_to :user
has_many :user_accessors, :foreign_key => "accessible_list_id", :dependent => :destroy
has_many :accessors, :class_name => "User", :through => :user_accessors
validates :title, :presence => true, :length => { :minimum => 1 }
attr_writer :authorized_users
after_save :add_accessors
def authorized_users
#authorized_users || self.accessors.map(&:username).join(' ')
end
private
def add_accessors
if #authorized_users
accessors = #authorized_users.split(' ').map do |username|
user = User.find_by_username(username)
if user
if self.user.inverse_friends.include? user
self.user_accessors.build(:accessor_id => user.id).accessor
end
end
end
end
end
end
The form used to create or update the list is the following one :
= simple_form_for [#user, #list] do |f|
= f.input :title, :label => "Titre"
= f.input :authorized_users, :label => "Authorized users", :hint => "Separated by spaces"
%p
= f.button :submit
So my problem comes from the fact that I don't know exactly how to create/update the accessors, my code self.user_accessors.build(:accessor_id => user.id).accessor definitely not working to fill it correctly.
I'm still quite a noob in rails (and ruby in general…), so I hope what I put there was relevant enough for you to help me! Thanks in advance!
I have set up a twitter-like following model. Users can all subscribe to each other. I am getting an error in my users controller when trying to create the relationship.
user.rb:
has_many :subscriptions
has_many :providers, :through => :subscriptions
has_many :followings, :class_name => "Subscription"
has_many :followers, :through => :followings
subscription.rb
belongs_to :provider, :class_name => 'User', :foreign_key => "provider_id"
belongs_to :follower, :class_name => 'User', :foreign_key => "follower_id"
users_controller.rb
69 def follow
70 logger.debug params.to_yaml
71 #user = User.find(params["user_id"])
72 logger.debug #user.to_yaml
73 if current_user.providers << #user
74 flash[:notice] = "Subscribed"
75 else
76 flash[:error] = "Unable to subscribe."
77 end
78 end
This is the error when I call follow:
ActiveRecord::UnknownAttributeError (unknown attribute: user_id):
app/controllers/users_controller.rb:73:in `follow'
I have verified that I ran rake db:migrate - the subscription table has two fields provider_id and follower_id. Can anyone help me with the error and explain why it is looking for a 'user_id' attribute?
Update:
show.html.erb:
<%= button_to "Subscribe", user_follow_path(#user), :remote => true %>
routes.rb:
resources :users do
resources :locations
resources :saved_events
resources :saved_locations
post "follow"
end
rake routes | grep follow:
user_follow POST /users/:user_id/follow(.:format) {:action=>"follow", :controller=>"users"}
Using Michael Hartl's tutorial as a guide, I came up with this solution, which fixes the data model so that collection functions work as they should.
Make the provider id accessible and remove the foreign keys in the subscription model.
subscription.rb:
attr_accessible :provider_id
belongs_to :provider, :class_name => 'User'
belongs_to :follower, :class_name => 'User'
Add foreign keys for subscriptions and reverse_subscriptions in the user model.
user.rb:
has_many :subscriptions, :foreign_key => "subscriber_id", :dependent => :destroy
has_many :subscribed_to, :through => :subscriptions, :source => :provider
has_many :reverse_subscriptions, :class_name => "Subscription", :foreign_key => "provider_id", :dependent => :destroy
has_many :followers, :through => :reverse_subscriptions
I also added helper methods to the user model.
user.rb:
def following?(provider)
subscriptions.find_by_provider_id(provider)
end
def follow!(provider)
subscriptions.create!(:provider_id => provider.id)
end
def unfollow!(provider)
subscriptions.find_by_provider_id(provider).destroy
end
Then, in the controller, we can call follow! or unfollow!
user_controller.rb:
...
current_user.unfollow!(#user)
...
current_user.follow!(#user)
...
The reason it's giving you a error is because the when you call << on the providers collection the user doesn't know it's supposed to be a follower. So it's basically saying, "I'm a user, add me to this collection of providers!" instead of "This guy is going to follow me, I'm now a provider and he's a follower"
The simplest answer may be to just do
user.rb:
def follow(other_user)
Subscription.create(:provider => other_user, :follower => self)
end
users_controller.rb
def follow
#user = User.find(params["user_id"])
if current_user.follow(#user)
flash[:notice] = "Subscribed"
else
flash[:error] = "Unable to subscribe."
end
end
I have a model Follow that defines a user_id and a followed_user_id. If you've used Twitter, this should make sense.
I'm trying to make followed_user_id point to a User model, so I can access the user that is being followed through f.followed_user (in the same way that if I have an Entry with belongs_to :user and a user_id column I can use entry.user to get the user.)
How can I do this?
Thanks!
Check this screencast
http://railscasts.com/episodes/163-self-referential-association
It shows how a self referential association (what you are referring here) should be implemented in Rails.
# models/user.rb
has_many :friendships
has_many :friends, :through => :friendships
has_many :inverse_friendships, :class_name => "Friendship", :foreign_key => "friend_id"
has_many :inverse_friends, :through => :inverse_friendships, :source => :user
# friendships_controller.rb
def create
#friendship = current_user.friendships.build(:friend_id => params[:friend_id])
if #friendship.save
flash[:notice] = "Added friend."
redirect_to root_url
else
flash[:error] = "Unable to add friend."
redirect_to root_url
end
end
def destroy
#friendship = current_user.friendships.find(params[:id])
#friendship.destroy
flash[:notice] = "Removed friendship."
redirect_to current_user
end
You can do it like this:
belongs_to :followed_user, :class_name => "User"
This article walks you through exactly what you need to know on how to solve this issue:
http://www.spacevatican.org/2008/5/6/creating-multiple-associations-with-the-same-table
Straight from the article:
class Sale < ActiveRecord::Base
belongs_to :buyer, :class_name => 'User', :foreign_key => 'buyer_id'
belongs_to :seller, :class_name => 'User', :foreign_key => 'seller_id'
end
class User < ActiveRecord::Base
has_many :purchases, :class_name => 'Sale', :foreign_key => 'buyer_id'
has_many :sales, :class_name => 'Sale', :foreign_key => 'seller_id'
end
The article explains in full what, why and how.