I'm trying to show all messages that belong to each channel on that channels index pages, is there a simple way to do this?
class MessagesController < ApplicationController
def index
#channel = Channel.find(params[:channel_id])
#messages = #channel.messages
end
def new
#channel = Channel.find(params[:channel_id])
#message = #channel.messages.build
end
def create
#channel = Channel.find(params[:channel_id])
#message = #channel.messages.build(params[:message])
if #message.save
flash[:notice] = "Successfully created message."
redirect_to channel_url(#message.channel_id)
else
render :action => 'new'
end
end
def edit
#message = Message.find(params[:id])
end
def update
#message = Message.find(params[:id])
if #message.update_attributes(params[:message])
flash[:notice] = "Successfully updated message."
redirect_to channel_url(#message.channel_id)
else
render :action => 'edit'
end
end
def destroy
#message = Message.find(params[:id])
#message.destroy
flash[:notice] = "Successfully destroyed message."
redirect_to channel_url(#message.channel_id)
end
end
&
class ChannelsController < ApplicationController
def index
#channels = Channel.find(:all)
end
def show
#channel = Channel.find(params[:id])
#message = Message.new(:channel => #channel)
end
def new
#channel = Channel.new
end
def create
#channel = Channel.new(params[:channel])
if #channel.save
flash[:notice] = "Successfully created channel."
redirect_to #channel
else
render :action => 'new'
end
end
def edit
#channel = Channel.find(params[:id])
end
def update
#channel = Channel.find(params[:id])
if #channel.update_attributes(params[:channel])
flash[:notice] = "Successfully updated channel."
redirect_to #channel
else
render :action => 'edit'
end
end
def destroy
#channel = Channel.find(params[:id])
#channel.destroy
flash[:notice] = "Successfully destroyed channel."
redirect_to channels_url
end
end
&
MyApp::Application.routes.draw do
resources :users
resources :channels , :has_many => :messages, :shallow => true
resources :messages , :only => [:index]
root :channels
resources :users, :user_sessions
match 'login' => 'user_sessions#new', :as => :login
match 'logout' => 'user_sessions#destroy', :as => :logout
match ':controller(/:action(/:id(.:format)))'
#root :to => 'channels#index', :as => :listchannels
end
Assuming two models Channel and Message, where a channel has many messages, you could do something like this:
# controller
#channel = Channel.find(params[:channel_id])
#messages = #channel.messages
# index.html.erb
<% #messages.each do |message| %>
<%=h message.content %><br>
<% end %>
where content is some attribute of Message
Related
This is the issue I am having, Haven't been able to get around it. Now this happens while logging into the account. I haven't had this issue before til last night.
Here is my users_controller.rb,
class UsersController < ApplicationController
before_action :set_user, only: [:edit, :update, :destroy]
before_action :correct_user, only: [:edit ]
after_action :signed_in_after_register, only: :create
def index
#users = User.all
#user = User.find(session[:user_id])
if params[:search]
#users = User.search(params[:search]).order("created_at DESC")
else
#users = User.all.order('created_at DESC')
end
end
def dashboard
#user = User.find(session[:user_id]) unless session[:user_id] == ""
redirect_to login_path, notice: "You're not logged in" unless #user
#posts = #user.posts.order("created_at DESC").limit(3)
#comment = Comment.new
#post = Post.new
end
def newsfeed
#user = User.find(session[:user_id]) unless session[:user_id] == nil
redirect_to login_path, notice: "You're not logged in" unless #user
#posts = #user.posts.order("created_at DESC").limit(3)
end
def nav
#user = User.find(session[:user_id])
end
def posts
#user = User.find(session[:user_id])
#posts = #user.posts
end
def destroy
#user = User.find(session[:user_id]) unless session[:user_id] == ""
redirect_to login_path, notice: "You're not logged in" unless #user
end
def welcome
#user = User.find(params[:user_id]) unless session[:user_id] == ""
redirect_to login_path, notice: "You're not logged in" unless #user
#user = User.find(session[:user_id])
end
def show
#user = User.find(params[:user_id]) unless session[:user_id] == ""
redirect_to login_path, notice: "You're not logged in" unless #user
#posts = #user.posts.order("created_at DESC").limit(3)
#comment = Comment.new
#post = Post.new
end
def new
#user = User.new
#post = Post.new(params[:post_id])
end
def edit
#user = User.find(params[:user_id]) if params[:user_id]
redirect_to #dashboard_path unless #user
end
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to dashboard_path, notice: 'User was successfully created!' }
format.json { render :profile, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
def update
if #user == current_user
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to dashboard_path, notice: 'User was successfully updated.' }
format.json { render :profile, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
else
redirect_to dashboard_path, notice: 'You do not have permission to edit the profile of another user.'
end
end
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_user
#user = User.find(params[:id])
end
def correct_user
#user = User.find(params[:id]) unless session[:user_id] == ""
end
def signed_in_after_register
session[:user_id] = #user.id
end
def user_params
params.require(:user).permit(:first_name, :last_name, :bio, :comments, :password, :password_confirmation, :email, :age, :profile_picture, :post, :body)
end
end
Heres my comments _form.html.erb,
<%= form_for([#post, #comment]) do |f| %>
<p>
<%= f.text_area :body, placeholder: "Write a comment!" %>
</p>
<br>
<p> <%= f.submit %> </p>
<% end %>
And here is my routes.rb,
Rails.application.routes.draw do
root 'welcome#welcome'
get 'login' => 'sessions#login', :as => :login
get 'dashboard' => 'users#dashboard', :as => :dashboard
post 'logging/user' => 'sessions#create'
get 'logout' => 'sessions#destroy', :as => :logout
get 'about' => 'about'
get 'newsfeed' => 'users#newsfeed'
resources :users, except: :show
get 'profile/:user_id' => 'users#show', as: :profile
get 'location' => 'location#location'
resources :posts do
resources :comments
end
get 'index' => 'posts#index'
get 'register' => 'users#new', :as => :register
end
If you guys do need to see anymore code then just let me know, I will post it! Thank you so much in advance!
The problem is you're trying to create a URL that looks like this: /posts/:post_id/comments by passing form_for([#post, #comment]). It's OK that #comment isn't saved to the database, but the #post you use must already be saved to the database because you can't create that URL without #post having an ID.
Once #post is saved, it'll have an ID, so you can generate the route: for example, /posts/32/comments.
Check your dashboard.html.erb file for where you're using #posts and rendering comments/_form.html.erb. You may have a post object available, and you should use it in your form instead: form_for([post, #comment]).
You'll probably also want to remove the #post = Post.new line from your #dashboard controller action.
So that multiple people can be an administrator to a business page, we've created a model called administration where people can apply to be an admin of a business and thus the status of "0" is "pending" and "1" is accepted.
How can I prevent users from editing a page where their status for i is still "0" (pending).
class Administration < ActiveRecord::Base
attr_accessible :business_id, :user_id, :status
belongs_to :user
belongs_to :business
scope :pending, where('status = ?',0).order("updated_at desc")
def self.new_by_user_business( user, business)
admin = self.new
admin.business_id = business.id
admin.user_id = user.id
admin.status = 0
admin.save!
end
end
Here is the current "edit page"
<h1>Editing business</h1>
<%= render 'form1' %>
Here is the business controller.
class BusinessesController < ApplicationController
respond_to :html, :xml, :json
before_filter :authenticate_user!, except: [:index, :show]
def index
#businesses = Business.all
respond_with(#businesses)
end
def show
#business = Business.find(params[:id])
if request.path != business_path(#business)
redirect_to #business, status: :moved_permanently
end
end
def new
#business = Business.new
3.times { #business.assets.build }
respond_with(#business)
end
def edit
#business = get_business(params[:id])
#avatar = #business.assets.count
#avatar = 3-#avatar
#avatar.times {#business.assets.build}
end
def create
#business = Business.new(params[:business])
if #business.save
redirect_to #business, notice: 'Business was successfully created.'
else
3.times { #business.assets.build }
render 'new'
end
end
def update
#business = get_business(params[:id])
if #business.update_attributes(params[:business])
flash[:notice] = "Successfully updated Business."
end
#avatar = #business.assets.count
#avatar = 3-#avatar
#avatar.times {#business.assets.build}
respond_with(#business)
end
def destroy
#business = get_business(params[:id])
#business.destroy
respond_with(#business)
end
def my_business
#business = Business.all
end
def business_tickets
#user = current_user
#business = get_business(params[:id])
#tickets = #business.tickets
#business_inbox = TicketReply.where(:email => #business.callred_email)
end
def your_business
#user = current_user
#business = get_business(params[:id])
if #business.users.map(&:id).include? current_user.id
redirect_to my_business_businesses_path, notice: 'You are already an administator of this business.'
else
#admin = Administration.new_by_user_business( #user, #business)
BusinessMailer.delay(queue: "is_your_business", priority: 20, run_at: 5.minutes.from_now).is_your_business(#user,#business)
redirect_to #business, notice: 'Thank you for claiming your business, and we will be in touch with you shortly.'
end
end
def view_message
# #business = Business.find(params[:business_id])
#ticket = Ticket.find(params[:id])
#reply = #ticket.ticket_replies
end
private
def get_business(business_id)
#business = Business.find(business_id)
end
end
You could add a before_filter to check the status. You will have to change some of the logic but this is the idea
class BusinessesController < ApplicationController
before_filter :restrict_access, :only => [:edit, :update]
private
def restrict_access
#business = get_business(params[:id])
redirect to root_path, :notice => "Not Authorized" unless current_user.status == 1
end
end
I have internal messages in my application. I am using devise and I have installed password module but did not configured it yet. when I tried to press on Forget Password? I got this error:
No route matches {:controller=>"messages", :mailbox=>:inbox, :user_id=>nil}
So what I need is: How to solve this problem ? and How to make the forget password feature works for action mailer so user can reset his password using the email which saved in the database.
Note: Before installing internal messages into my app , when i tried to click forget password link it was redirecting normally.
I am using another controller for registration instead of that one by devise and on signup , users are added by admin.
this is from my routes file
devise_for :users, :controllers => { :registrations => "users" }
resources :users, only: [:index, :new, :create, :show, :destroy, :edit, :update] do |user|
resources :messages do
collection do
post 'delete_multiple'
end
end
end
Forget Password link
<%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
<%= link_to "Forgot your password?", new_password_path(resource_name), :class => "btn btn-danger" %><br />
<% end -%>
Users_Controller.rb
class UsersController < ApplicationController
load_and_authorize_resource
def index
#users = User.all
#users_grid = initialize_grid(User,
:per_page => 5)
end
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
flash[:notice] = 'A new user created successfully.'
redirect_to users_path
else
flash[:error] = 'An error occurred please try again!'
redirect_to users_path
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(params[:user])
flash[:notice] = 'Profile updated'
redirect_to users_path
else
render 'edit'
end
end
def destroy
#user = User.find(params[:id])
if current_user == (#user)
flash[:error] = "Admin suicide warning: Can't delete yourself."
else
#user.destroy
flash[:notice] = 'User deleted'
redirect_to users_path
end
end
end
Messaages_controller.rb
class MessagesController < ApplicationController
before_filter :set_user
def index
if params[:mailbox] == "sent"
#messages = #user.sent_messages
elsif params[:mailbox] == "inbox"
#messages = #user.received_messages
#elsif params[:mailbox] == "archieved"
# #messages = #user.archived_messages
end
end
def new
#message = Message.new
if params[:reply_to]
#reply_to = User.find_by_id(params[:reply_to])
unless #reply_to.nil?
#message.recepient_id = #reply_to.id
end
end
end
def create
#message = Message.new(params[:message])
#message.sender_id = #user.id
if #message.save
flash[:notice] = "Message has been sent"
redirect_to user_messages_path(current_user, :mailbox=>:inbox)
else
render :action => :new
end
end
def show
#message = Message.readingmessage(params[:id],#user.id)
end
def delete_multiple
if params[:delete]
params[:delete].each { |id|
#message = Message.find(id)
#message.mark_message_deleted(#message.id,#user.id) unless #message.nil?
}
flash[:notice] = "Messages deleted"
end
redirect_to user_messages_path(#user, #messages)
end
private
def set_user
#user = current_user
end
end
Since it's showing user_id => nil. Can you check if your session is not expired
I have a Question & Answer feature and I am just about finished with it. I have no idea how to do the code that would send a message to user when another user has asked them a question. For example, User A sends User B a question, a inbox message is sent to User B notifying them that they have a new question.
There's two ways I thought how to go about this.
Method #1
Inside the message it will link user to the page with the Question on it so it can be answered
Method #2
Inside the message it will include the question that was asked. User can reply to message which would submit as their answer.
Questions controller:
respond_to :js, :html
def index
#questions = Question.all
respond_with(#questions)
end
def show
#question = Question.find(params[:id])
#questions = Question.order("created_at DESC")
respond_with(#questions)
end
def new
#question = Question.new
respond_with(#question)
end
def create
#question = Question.new(params[:question])
if #question.save
redirect_to questions_path, notice: 'Your question was saved successfully. Thanks!'
else
render :new, alert: 'Sorry. There was a problem saving your question.'
end
end
end
Answers controller:
def new
#question = Question.find(params[:question_id])
end
def create
#question = Question.find(params[:question_id])
if #question.update_attributes(params[:question])
redirect_to questions_path
else
render :new
end
end
end
Messages controller:
before_filter :set_user
def index
if params[:mailbox] == "sent"
#messages = #user.sent_messages
elsif params[:mailbox] == "inbox"
#messages = #user.received_messages
#elsif params[:mailbox] == "archived"
# #messages = #user.archived_messages
end
if params[:mailbox] == "unread"
#messages = #user.unread_messages
end
end
def new
#message = Message.new
if params[:reply_to]
#reply_to = User.find_by_sender_id(params[:reply_to])
unless #reply_to.nil?
#message.recipient_id = #reply_to.sender_id
end
end
end
def create
#message = Message.new(params[:message])
#message.sender_id = #user.id
if #message.save
flash[:notice] = "Message has been sent"
redirect_to user_messages_path(current_user, :mailbox=>:inbox)
else
render :action => :new
end
end
def show
#message = Message.find(params[:id])
#message.readingmessage if #message.recipient == current_user
end
def destroy
#message = Message.find(params[:id])
#message.destroy
flash[:notice] = "Successfully deleted message."
redirect_to user_messages_path(#user, #messages)
end
def delete_multiple
if params[:delete]
params[:delete].each { |id|
#message = Message.find(id)
#message.mark_message_deleted(#message.id,#user.id) unless #message.nil?
}
flash[:notice] = "Messages deleted"
end
redirect_to user_messages_path(#user, #messages)
end
private
def set_user
#user = current_user
end
end
Message model:
attr_accessible :subject, :body, :sender_id, :recipient_id, :read_at,:sender_deleted,:recipient_deleted
validates_presence_of :subject, :message => "Please enter message title"
has_many :notifications, as: :event
scope :unread, -> {where('read_at IS NULL')}
scope :not_deleted_by_recipient, where('messages.recipient_deleted IS NULL OR messages.recipient_deleted = ?', false)
scope :not_deleted_by_sender, where('messages.sender_deleted IS NULL OR messages.sender_deleted = ?', false)
belongs_to :sender,
:class_name => 'User',
:foreign_key => 'sender_id'
belongs_to :recipient,
:class_name => 'User',
:foreign_key => 'recipient_id'
# marks a message as deleted by either the sender or the recipient, which ever the user that was passed is.
# When both sender and recipient marks it deleted, it is destroyed.
def mark_message_deleted(id,user_id)
self.sender_deleted = true if self.sender_id == user_id
self.recipient_deleted = true if self.recipient_id == user_id
(self.sender_deleted && self.recipient_deleted) ? self.destroy : self.save!
end
# Read message and if it is read by recipient then mark it is read
def readingmessage
self.read_at ||= Time.now
save
end
# Based on if a message has been read by it's recipient returns true or false.
def read?
self.read_at.nil? ? false : true
end
def self.received_by(user)
where(:recipient_id => user.id)
end
def self.not_recipient_deleted
where("recipient_deleted = ?", false)
end
def self.sent_by(user)
Message.where(:sender_id => user.id)
end
def previous(same_recipient = true)
collection = Message.where('id <> ? AND created_at > ?', self.id, self.created_at).order('created_at ASC')
collection = collection.where(recipient_id: self.recipient_id) if same_recipient
collection = collection.not_deleted_by_recipient
collection.first
end
def next(same_recipient = true)
collection = Message.where('id <> ? AND created_at < ?', self.id, self.created_at).order('created_at DESC')
collection = collection.where(recipient_id: self.recipient_id) if same_recipient
collection = collection.not_deleted_by_recipient
collection.first
end
end
private
def send_notification(message)
message.notifications.create(user: message.recipient)
end
I have solved this.
Questions Controller:
def create
#question = Question.new(params[:question])
if #question.save
#message = Message.create(:subject => "Hey you have a message from #{#question.sender_id}",
:sender_id => #question.sender_id,
:recipient_id => #question.recipient_id,
:body => #question.question)
#question.message = #message
#question.save
redirect_to questions_path, notice: 'Your question was saved successfully. Thanks!'
else
render :new, alert: 'Sorry. There was a problem saving your question.'
end
end
Every time a notification is needed, you should create it. It would go for having a Notification model that takes at least the object for which the notification was created, the user that the notification goes to and a flag whether it has been read or not.
To display the notifications, the easiest way of course is to integrate that into your layout file and do something like this:
Notification.where(:user_id => #current_user).size > 0
<%= "You have #{Notification.where(:user_id => #current_user).size} notification(s)" %>
end
And to nicen things up you can create a scope inside of the Notification object which will give you the notifications for a specific user. Of course if you want all the magic like Stackoverflow has with updating the notifications through AJAX calls, you will have to do some JavaScript lifting.
I have this as my create method inside my PostsController
class PostsController < ApplicationController
def create
#user = current_user
#post = current_user.posts.build(params[:post])
if #post.save
flash[:success] = "Post created!"
redirect_to root_path
else
#feed_items = current_user.feed.paginate(:per_page => "10", :page => params[:page])
render 'pages/home'
end
end
I'd like to change it slightly to also set :user_id => params[:post][:user_id]. I'm trying this but it doesn't include the current_user so I am wondering how are these create methods different and how would I keep the same functionality in current_user.posts.build(params[:post]) with Post.new ?
def create
#post = Post.new :user_id => params[:post][:user_id]
#post.update_attributes params[:post]
if #post.save
flash[:success] = "Post created!"
redirect_to root_path
else
#feed_items = current_user.feed.paginate(:per_page => "10", :page => params[:page])
render 'pages/home'
end
end
end
in your post model belongs_to :user
def create
#post = Post.new(params[:post])
#post.user = current_user
if #post.save
flash[:success] = "Post created!"
redirect_to root_path
else
#feed_items = current_user.feed.paginate(:per_page => "10", :page => params[:page])
render 'pages/home'
end
end
end