Passing ID from one controller to another - ruby-on-rails

So I am developing a job portal website, and I am looking to pass the current job ID over to the "job applications" controller #new method, but I am having issues being able to do so.
So when a user clicks the "Job_applications#new", It gets the current page job_id.
Models
Class Job
has_many :job_applications
end
Class JobApplication
belongs_to :job
end
In my Job_Applications Controller
def create
#job = Job.find(params[:id])
*Additional save & Redirect methods*
end
In my View I have the following code
<%= link_to "Apply Now",new_job_application_path(:id => #job.id), class: "btn btn-primary" %>
I know I am doing something stupid here, Ideally, I would like to pass the job id without it being in the URL
Example
domain.com/job_application/new
However this method shows this
domain.com/job_application/new?id=3
Any help greatly appreciated

When you call
new_job_application_path(id: #job.id)
You should be able to retrieve it like you are doing:
#job = Job.find(params[:id])

if you want your params to not appear in the url, u got to use a POST request.
However, note that using a post request for a 'new' action is not 'Restful', which is what Rails is based on, but its not impossible.
Read more on 'Restful routes' here.

Related

How to display create page/form within a separate controllers show page?

I would like to have the ability to create an order directly from the listings show page instead of having to be directed to a new orders page.
I have a Listing (listingcontroller show method) which can be purchased by clicking a button to go to an orders page (orderscontroller create method).
In what way can I have the order form directly on the listings show page?
I have tried adding the form, but I get error:
First argument in form cannot contain nil or be empty
<%= form_for([#listing, #order]) do |form| %>
When I take the Orders controller create method and put it in the Listings Controller Show method i get this error:
Couldn't find Listing without an ID
Here's the form_for I want within the Listings Show Page:
<%= form_for([#listing, #order]) do |form| %>
....
Orders Controller create:
#order = Order.new(order_params)
#listing = Listing.find(params[:listing_id])
#seller = #listing.user
#order.listing_id = #listing.id
#order.buyer_id = current_user.id
#order.seller_id = #seller.id
...
Routes:
resources :listings do
resources :orders
end
listing model:
has_many :orders
category model:
has_and_belongs_to_many :listings
I tried taking the orders create method and injecting it into the Listings show method with "def create" and without. I put "#listing = Listing.find(params[:listing_id])" ahead of the create method (when using "def create" and i would still get the error it needs an id. Even when I get that error, at the bottom of the webpage the request shows the listing ID is there.
I tried using a hidden field in the form but didn't work for me.
Do I need to do something to the controllers or is there a way to load the :listing_id into the form somehow. This is probably something very quick and simple for some of you but why won't it load on the listings show page, but loads fine in the orders create page?
Easy approach.
Your show action in listing_controller.rb should have the following code:
def show
#listing = Listing.find(params[:listing_id])
#order = #listing.orders.build
.
.
.
end
Your views/listings/show.erb should have the following code
<%= form_for(#order, url: listing_orders_path(#listing)) do |f| %>
.
.
.
<%= end %>
This way you create an order to the listing (in memory) before you submit the form. You can add the listing id as a hidden field.
After submit the order you modify your orders_controller.rb this way:
def create
#listing = Listing.find(params[:listing_id])
#order = #listing.orders.build(params[...]) #select the params you need for the order creation. Since you create the order directly to the listing you don't need to add the listing_id to the order.
if #order.save
#do something
else
#do something
end
end
Keep in mind that using params[] directly you have security problems, please check about mass assignment: https://guides.rubyonrails.org/v3.2.8/security.html
You can achieve that by using AJAX call, where you will pass the url of orders action and other params. There will be no reload of page and you'll get the functionality right on the listings page.
Here is the link to have a look - How AJAX calls work.

Create a link to a defined method?

As my first Rails app, I'm trying to put together a simple blog application where users can vote on posts. I generated the Blogpost scaffold with a integer column (entitled "upvote") for keeping track of the vote count.
In the Blogpost model, I created a function:
def self.voteup
blogpost.upvote += 1
end
On the Blogpost index view, I'd like to create a link that does something like:
link_to "Vote up" self.voteup
But this doesn't seem to work. Is it possible to create a link to a method? If not, can you point me in the right direction to accomplish this?
What you are trying to do goes against the MVC design principles. You should do the upvoting inside a controller action. You should probably create a controller action called upvote. And pass in the post id to it. Inside the controller action you can retrive the post with the passed in ID and upvote it.
if you need serious voting in your rails app you can take a look at these gems
I assume that you need to increment upvote column in blogspots table. Redirection to a method is controllers job and we can give links to controller methods only. You can create a method in Blogposts controller like this:
def upvote_blog
blogpost = Blogpost.find(params[:id])
blogpost.upvote += 1
blogpost.save
redirect_to blogpost_path
end
In your index page,
<% #blogposts.each do |blogpost| %>
...
<%= link_to "Vote up", :action => upvote_blog, :id => blogpost.id %>
...
<% end %>
You can not map Model method to link_to in view. you can create an action in controller to access the Model method and map it using link_to, also if the action is other than CRUD, then you should define a route for the same in route.rb

Rails, redirect from NEW to CREATE

Hey all, I'm writing an app to handle registration for athletic events. Some of these events have multiple athletes per entry, while some have only a single athlete. I'm currently sending the athlete to the NEW action on BoatsController like so:
<%= link_to 'Register', new_event_boat_path(#event) %>
My question is, if the NEW action sees that the event only requires one user per boat, how can I forward the user directly to the CREATE action? More concisely, how can I generate a POST from within an action?
You dont need to do anything fancy. The create action is just a method in your controller. You can call it just like any other method:
def new
if event_only_requires_one_user_per_boat
create
else
#display new form
end
end
Also, this technique prevents the user from having to make multiple requests since it doesn't make the user redirect.
You could instead create a method that encapsulates most of the code from your create action, and invoke it from create (with params as usual) and from your special case in new (sending in data from your user object).
def new
#assuming boats is an array
if boats.size > 1
redirect_to boats_path(:user => params[:user], :boat => params[:boat]), :method => :post
else
#new stuff
end
end
boats_path or whatever object you are trying to create.

Sending messages between users

I am building an application and it needs to have a feature whereby one user can send another user a message. The system can be the most basic type available in rails and that would suit me fine.
Any ideas on how to go about this?
Thanks.
Table structure like this:
Users
name,pwd
Messages
title,body
UserMessages
user_id,message_id
Why don't you use acts_as_messageable plugin:http://www.philsergi.com/2007/10/actsasmessageable-plugin-released_04.html ?
Similarly, there are other plug-ins for authentication (restful authentication).
So i have implemented the DB tables and now need to pass the data around my system which im finding quite troubling. When the user clicks "send message to" on my form i need it to carry the id of the profile which the user is viewing. I thought this would do that:
<%= link_to "Message", :action => 'message', :id => #user.id %>
Now this pass the persons ID who i was looking to the message action (i know #user.id should work because i use #user.detail to view other details about the user on that page)
My controller should then receive that #user.id, heres my controller:
def message
#reciever = User.find_by_id(params[:id])
end
and in my view for i want to show the recievers id so i thought that
<label>Send Message To: <%= render :text => #reciever.id %></label>
would be suffiencent.
Any ideas?

Ruby on Rails: Confirmation Page for ActiveRecord Object Creation

Using Ruby on Rails I want a confirmation page before creating an ActiveRecord object. The user will see a preview of the item they are creating before submitting and the object being saved in the database
A common pattern;
User visits /entry/new
User enters details and clicks submit
User is redirected to /entry/confirm which displays the entry and clicks submit or edit to correct mistakes
Object is saved
How would you implement it?
Another option to solve this issue adding by a virtual confirmation attribute to your model. This way, there is no need to create a separate action for this:
class MyRecord < ActiveRecord::Base
attr_accessor :confirmation
validates_acceptance_of :confirmation, :on => :create
end
Now, your new object will not save correctly because the validation will fail on the confirmation field. You can detect this situation and present something like this:
<% form_for(#my_record) do |form| %>
...
<%= form.check_box :confirmation %> Really create this record.
<%= submit_tag('Confirm') %>
<% end %>
I would probably add a "preview" action to the routes.rb file for that model:
map.resource :objects, :new => { :preview => :post }
You would get to this preview action by POSTing the preview_object_url named route. You would need to essentially create the Object in the same way you would in your create action, like this:
def preview
#object = Object.new(params[:object])
end
This page would then POST to the create action, which would then create the Object. It's pretty straight forward.
http://api.rubyonrails.org/classes/ActionController/Resources.html
A few options
1- store the object you want to create in the session until you hit the confirm page, then just save it
2- pass around the object w/ each Post/submit from new -> details -> confirm
I would probably go with 2, since I am not prone to saving state with the session.
I'm not sure how to do this (RoR is new to me) but you could just specify the action for /new as /confirm, and then it calls create.
Right?

Resources