Add custom attributes in the mailboxer gem - ruby-on-rails

I have used mailboxer gem for the messaging between users in my website.
Which is based on spree module.
I want to add the product id with the conversation so user can filter the conversations according to the products.
How can I achieve this?
Here is the code for message_controller file:
module Spree
module Admin
class MessagesController < Spree::BaseController
before_action :authenticate_spree_user!
def index
filtered_messages = Mailboxer::Message.ads_id(params[:ad_id])
end
def new
#chosen_recipient = Spree::User.find_by(id: params[:to].to_i) if params[:to]
end
def create
product_id = params[:product_id]
recipients = Spree::User.where(id: params['recipients'])
conversation = current_spree_user.send_message(recipients, params[:message][:body], params[:message][:subject], params[:product_id]).conversation
flash[:success] = 'Message has been sent!'
redirect_to '/admin/conversations'
end
private
def conversation_params
#params.require(:mailboxer_conversations).permit(:ad_id)
params.permit(:ad_id)
end
end
end
end

Related

Only allow owner of data to access

I'm use devise, and belongs_to to quickly add relations. For example:
rails generate devise User
rails generate scaffold Campaign name:string user:belongs_to
Tell me please, how can I allow access to data only for the owner of this data?
Users can access their campaigns as this:
current_user.campaigns
CampaignsController
def show
#this will search only within current user campaigns.
#campaign = current_user.campaigns.find_by(id: params[:id]).
if campaign
#this campaign exists and its from current_user
...
end
end
def index
#only this user campaigns
#campaigns = current_user.campaigns
end
def new
#campaign = current_user.campaigns.build
end
def create
#This campaign is created with user_id = current_user.id
#campaign = current_user.campaigns.build(campaign_params)
#campaign.save
end
private
def campaign_params
params.require(:campaign).permit(:name)
end

Adding search function for gem mailboxer

I'm new to Rails, and I found this gem mailboxer for sending messages between the website users. I am unable to write the search functions for inbox and sent.
conversations controller
class ConversationsController < ApplicationController
before_action :authenticate_user!
def new
end
def create
recipients = User.where(id: conversation_params[:recipients])
conversation = current_user.send_message(recipients, conversation_params[:body], conversation_params[:subject]).conversation
flash[:success] = "Your message was successfully sent!"
redirect_to conversation_path(conversation)
end
def show
#receipts = conversation.receipts_for(current_user)
# mark conversation as read
conversation.mark_as_read(current_user)
end
def reply
current_user.reply_to_conversation(conversation, message_params[:body])
flash[:notice] = "Your reply message was successfully sent!"
redirect_to conversation_path(conversation)
end
def trash
conversation.move_to_trash(current_user)
redirect_to mailbox_inbox_path
end
def untrash
conversation.untrash(current_user)
redirect_to mailbox_inbox_path
end
private
def conversation_params
params.require(:conversation).permit(:subject, :body,recipients:[])
end
def message_params
params.require(:message).permit(:body, :subject)
end
end
What do I need to do to implement these?
I am not aware of the gem you are talking about. However, in general, you could do something like this in Rails.
Assuming you have a model Message, with name as a column, you could do this:
Message.where("name like ?", params[:name])
where params[:name] could be either "inbox" or "sent".

Ruby on Rails CRUD

I am building an application that allows users to create a trip. However, for some reason I am not sure if I am truly utilizing the power of rails or am I being redundant in my code. In the following example you will see a trip controller where a trip can be created and then displayed. Everything works, I just want to make sure I am going about it in the most minimal fashion.
class TripsController < ApplicationController
def new
#user = User.find(session[:id])
#trip = Trip.new
end
def create
#trip = Trip.create(trip_params)
#user = User.find(session[:id])
redirect_to user_trip_path(#user.id, #trip.id)
end
def show
#trip = Trip.find(params[:id])
end
private
def trip_params
params.require(:trip).permit(:where, :when, :price_per_person)
end
end
To tighten it up, "scope the trip to the user".
class TripsController < ApplicationController
before_filter :find_user
def new
#trip = #user.trips.build #assuming a User has many trips
end
def create
#trip = #user.trips.create(trip_params) #you may want to add an if else here to catch bad trips
redirect_to user_trip_path(#user.id, #trip.id)
end
def show
#trip = #user.trips.find(params[:id])
end
private
def trip_params
params.require(:trip).permit(:where, :when, :price_per_person)
end
def find_user
#user = User.find(session[:id]) # or current_user if you are using popular authentication gems
end
end
It's about readability too, not just less lines.

Mailboxer Gem, Admin View

I'm using the mailboxer gem for conversations/messages between the User model in my app. This is all working fine, thanks to some great help in stack overflow. I'm now trying to setup a section so admin can view all the conversations that are happening.
I have created a controller and view for conversations, nested in my admin section. I've pulled in all conversations on the index page with:
def index
#admin_conversations = Conversation.all
end
This has listed all the conversations, and a link to show each conversation, as expected.
The problem I am having, is that the mailboxer Gem is setup to only allow the current_user to view conversations that the current_user is a participant in. So I can click some of the conversations, (signed is as an admin) and see the contents, but some (that are between other test users) I cannot see i.e it throws an exception such as:
Couldn't find Conversation with id=5 [WHERE "notifications"."type" = 'Message' AND "receipts"."receiver_id" = 35 AND "receipts"."receiver_type" = 'User']
How can I define the method in my admin controller so that the admin can see everything?
I'm currently using cancan and allowing all 3 user roles I have (admin, client and supplier) like this:
can :manage, Conversation
...so it isn't a normal authorisation problem.
Here is my conversations controller:
class ConversationsController < ApplicationController
authorize_resource
helper_method :mailbox, :conversation
def create
recipient_emails = conversation_params(:recipients).split(',')
recipients = User.where(email: recipient_emails).all
conversation = current_user.
send_message(recipients, *conversation_params(:body, :subject)).conversation
redirect_to :back, :notice => "Message Sent! You can view it in 'My Messages'."
end
def count
current_user.mailbox.receipts.where({:is_read => false}).count(:id, :distinct => true).to_s
end
def reply
current_user.reply_to_conversation(conversation, *message_params(:body, :subject))
redirect_to conversation
end
def trash
conversation.move_to_trash(current_user)
redirect_to :conversations
end
def untrash
conversation.untrash(current_user)
redirect_to :conversations
end
private
def mailbox
#mailbox ||= current_user.mailbox
end
def conversation
#conversation ||= mailbox.conversations.find(params[:id])
end
def conversation_params(*keys)
fetch_params(:conversation, *keys)
end
def message_params(*keys)
fetch_params(:message, *keys)
end
def fetch_params(key, *subkeys)
params[key].instance_eval do
case subkeys.size
when 0 then self
when 1 then self[subkeys.first]
else subkeys.map{|k| self[k] }
end
end
end
end
The answer is probably something pretty silly, but I am new to this...
Thanks
In your conversation method, your calling mailbox.conversations.find(params[:id])
mailbox.conversations is what is limiting you to the current user's conversations.
Try just Conversation.find(params[:id])

Show username on Mailboxer inbox in Rails

I'm using the Mailboxer (https://github.com/ging/mailboxer) gem in my Rails app to handle private messages between users. As per the documentation, I'm using = render mailbox.inbox to show a list of all conversations (messages) for the logged-in user. However, the method only outputs the subject of the message. I need to show the sender of the message along with the subject. How can I edit this output so that the sender name is displayed?
The SQL table shows that the sender name is not stored in the conversations table, but on the notifications table via notifications_on_conversation_id (one to many). I tried to use <%= conversation.notifications.sender_id %> but I got the following error:
NoMethodError in Conversations#index
undefined method `notifications' for nil:NilClass
What can I add to the conversation controller and view in order to display the conversation's user and subject?
Thanks!
Conversations controller:
class ConversationsController < ApplicationController
before_filter :authenticate_user!
helper_method :mailbox, :conversation
def create
recipient_emails = conversation_params(:recipients).split(',')
recipients = User.where(email: recipient_emails).all
conversation = current_user.
send_message(recipients, *conversation_params(:body, :subject)).conversation
redirect_to conversation
end
def reply
current_user.reply_to_conversation(conversation, *message_params(:body, :subject))
redirect_to conversation
end
def trash
conversation.move_to_trash(current_user)
redirect_to :conversations
end
def untrash
conversation.untrash(current_user)
redirect_to :conversations
end
private
def mailbox
#mailbox ||= current_user.mailbox
end
def conversation
#conversation ||= mailbox.conversations.find(params[:id])
end
def conversation_params(*keys)
fetch_params(:conversation, *keys)
end
def message_params(*keys)
fetch_params(:message, *keys)
end
def fetch_params(key, *subkeys)
params[key].instance_eval do
case subkeys.size
when 0 then self
when 1 then self[subkeys.first]
else subkeys.map{|k| self[k] }
end
end
end
end
sender_id is available using receipt.notification.sender_id and .sender_type
for any conversation you can retrieve the receipts using:
#receipts = conversation.receipts_for
I ran on the same issue at some point and my solution was something like this: accessing current_user in mailboxer mailer notification

Resources