Use different variable depending on which view was used in Rails 4 - ruby-on-rails

I'm using Mailboxer so that users can reply to posts in my site. There are two types of post models in my site which users might reply to, Requests and Offers.
Here is my messages controller:
class MessagesController < ApplicationController
# GET /message/new
def new
#request = Request.find(params[:request])
#message = current_user.messages.new
#user = #request.user
end
def reply
#conversation ||= current_user.mailbox.conversations.find(params[:id])
end
# POST /message/create
def create
#user = User.find(params[:user])
#body = params[:body]
#subject = params[:subject]
current_user.send_message(#user, params[:body], params[:subject])
flash[:notice] = "Message has been sent!"
redirect_to :conversations
end
end
In the new action, I'm using #request, but if I reply to an Offer post, I'll need to use an #offer variable. Is there a way I can use an if statement to choose between an #offer and #request depending on the view the new action is called from? Is this the best way to go about this?

It's not the most graceful thing in the world but something as simple as this should work.
if params[:request]
#request = Request.find(params[:request])
else
#offer = Offer.find(params[:offer])
end

Related

Reroute to users show page

When I create an event on the users show page I want it to redirect back to the users show page if it indeed submitted correctly. Is there anyway I can do that here is my Events controller:
class EventsController < ApplicationController
def show
#event = Event.find(params[:id])
#songs = #event.songs.paginate(page: params[:page])
end
def create
#event = current_user.events.build(event_params)
if #event.save
flash[:success] = "Event Created!"
redirect_to 'user#show'
else
render 'welcome#index'
end
end
def destroy
end
private
def event_params
params.require(:event).permit(:name, :partycode)
end
end
Redirect to the user path and pass in the User ID.
redirect_to user_path(current_user.id)
Yes you can, but you'll need to use the actual path eg instead of redirect_to 'user#show' user:
redirect_to user_path(#event.user)

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".

How I Pass parameters from View to Controller In Ruby

#app/controllers/sessions_controller.rb
class SessionController < ApplicationController
def new
#session = Session.new
end
def fetch
##user = User.session(params [:user])
redirect_to "http://www.google.com"
end
def create
emai = params[:email]
puts emai
user = User.find_by(:email => session[:emai])
#user = User.find_by (params [:email])
#user = User.find_by email: 'abc#xyz.com'
#user = User.find_by(params[:Email])
#if (session[:Email] = user.email)
if (user)
redirect_to "http://www.yahoo.com"
flash[:notice] = "You signed up successfully"
flash[:color]= "valid"
else
flash[:notice] = "Form is invalid"
flash[:color]= "invalid"
redirect_to "http://www.google.com"
end
#redirect_to "http://www.yahoo.com"
end
end
every time i execute my view i get redirected to google.com even though i pass the parameters.
Edit by R Peck:
My logic should send people to Yahoo if the params are set, but still sends to Google, how can I fix this?
Try:
user = User.find_by(:email => params[:sessions][:emai])
You are not getting the value of email if you only call params[:email] you should call parent first before calling the child params[:sessions][:email].
Several things wrong with your code.
Here's what I'd write:
#app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
#session = Session.new
end
def create
email = params[:sessions][:email]
user = User.find_by email: email
url = user ? "google" : "yahoo"
colour = user ? "valid" : "invalid"
notice = user ? "You signed up successfully" : "Your form is invalid"
redirect_to "http://#{url}.com", notice: notice, color: colour
end
private
def session_params
params.require(:session).permit(:session, :params)
end
end
OOP
I think this may be a little advanced but I'll write it anyway, for my own benefit.
Rails is object orientated (it's built on Ruby which is an OOP language). This means that each time you create/call a controller, it should be centered around objects.
A good example for you would be the Devise controllers.
This has a sessions_controller which essentially allows you to CRUD (Create Read Update Destroy) a session. This is the correct way to use a controller.
Your implementation seems to be dealing with a user, rather than a session, and as such you'd be best using a users_controller to fix it:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new
#user.save
end
end
Having said that, it does seem that you're probably going to resolve the issue to make it so that you can use the User to build a new session.
I guess it's best to remember that you have to ensure you're able to appreciate a good structure for your application

rails - DRY up controller actions

I have a controller with a lot of code duplication such as:
class PostController < ApplicationController
def action1
end
...
def actionN
end
end
And basically each action do something like this:
def action
#post = Post.find(params[:id])
if #post.action(current_user)
flash[:notice] = "#{custom string for this action}"
else
flash[:notice] = "Problem with your request"
end
redirect_to root_url
end
I thought about a method in ApplicationController that takes an array of symbols and generate the other methods, such as:
def self.action_for(*args)
args.each do |method, string|
define_method method.to_sym do
#post = Post.find(params[:id])
if #post.send method.to_sym
flash[:notice] = string
else
flash[:notice] = "Problem with your request"
end
redirect_to root_url
end
end
end
And call in PostController:
action_for [:action1, "Congratulations!"], [:action2, "Cool action!"] ..
I think this solution is ugly, it makes the ApplicationController dirty and allow other controllers to call my actions.
Any idea to solve the code-duplication problem?
Why don't you make a single action which will receive some extra parameter, like msg? Then you can take advantage of built-in I18n support:
def some_action
#post = Post.find(params[:id])
if #post.action(current_user)
flash[:notice] = I18n.t("messages.#{params[:msg]}", default: "Wrong message type")
else
flash[:notice] = I18n.t("messages.problem")
end
redirect_to root_url
end
Or maybe that makes sense to allow your #post.action to return some message for your notice?
I don't think there's anything too ugly in this solution.
To limit the logic to one controller, you can define self.action_for in PostController, instead of ApplicationController, and call it below its definition.
Note that you're already passing in first elements in pairs as symbols, so to_sym calls in action_for are not necessary.

Rails: How do you create a new nested resource?

In my app, Users have Conversations, and Conversations have Messages. A Message belongs both to a User (as an author) and to a Conversation.
I want to create a new Message. This is the code I'm using right now in MessagesController.
def new
#user = current_user #currently logged in user
#conversation = Conversation.find(params[:id])
#message = #conversation.messages.build
end
def create
#conversation = Conversation.find(params[:conversation_id])
#message = #conversation.messages.build(params[:message])
if #message.save
redirect_to username_conversation(current_user, #message.conversation)
else
redirect_to root_url
end
end
params[:message] contains the message content ("content" => "I'm Spartacus").
This isn't working (probably because I'm not specifying the user/author when creating a new Message?). How do I make this work the Rails way?
Thanks.
You need to set the user manually. Only one property can be set using the short methods provided by Rails.
def new
#user = current_user #currently logged in user
#conversation = Conversation.find(params[:id])
#message = #conversation.messages.build
#message.user = user
end
def create
#conversation = Conversation.find(params[:conversation_id])
#message = #conversation.messages.build(params[:message])
#message.user = current_user
if #message.save
redirect_to username_conversation(current_user, #message.conversation)
else
redirect_to root_url
end
end

Resources