Inside my application I have three models: user, pub and micropost.
I would like that when I the user creates a micropost on the pub page, a record of the micropost object is saved in the db with the user id and the pub id. To do this in the micropost table I have user_id and pub_id.
The problem is this: the user has to create the micropost when he is on the page showing the pub informations. I would like that after the user presses the button, the page is refreshed and the new micropost is shown. I cannot figure out how to get the id of the pub from the URL and pass it to the create method in the micropost controller, so to create the new micropost with the pub_id also. I can get the user_id from the current_user variable. When the user creates the micropost, the URL changes to /microposts
and the id is not found, so maybe my problem is how to save the id from the previus URL so when the user creates the microposts, it is saved with the pub's id.
micropost.rb
class Micropost < ApplicationRecord
belongs_to :user
belongs_to :pub
default_scope -> { order(created_at: :desc) }
validates :user_id, presence: true
validates :content, presence: true, length: { maximum: 240 }
validates :pub_id, presence:
end
micropost_controller.rb
class MicropostsController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
def create
@pub = Pub.find(params[:id]) // @pub gets nil value
@micropost = current_user.microposts.create!(micropost_params)
@micropost.pub= @pub // not sure about that
if @micropost.save
flash[:success] = "Micropost created!"
redirect_to(:back)
else
render 'static_pages/home'
end
end
def destroy
end
private
def micropost_params
params.require(:micropost).permit(:content, :pub_id)
end
end
_micropost_form.html.erb
<%= form_for(@micropost) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose new micropost..." %>
</div>
<%= f.submit "Post", class: "btn btn-primary" %>
<% end %>
pub.rb
class Pub < ApplicationRecord
belongs_to :user
has_many :microposts, dependent: :destroy
validates :user_id, presence: true
validates :address, presence: true, length: {maximum: 140, minimum: 20}
validates :name, presence: true, length: {maximum: 30, minimum: 5}
end
So my main problem is that I cannot build the new micropost because I cannot have access to the @pub variable from the micropost controller. When the user presses the button, it gets to /microposts route but then I redirect it back so to show me the new micropost on the pub's page. How can I resolve/improve this situation?
Thanks for your help!
Here is one solution based on the given information:
Rails.application.routes.draw do
resources :micropost
resources :pub do
resources :micropost
end
end
<%= form_for([@pub, @micropost]) do |f| %>
class MicropostsController < ApplicationController
def create
@pub = Pub.find(params[:pub_id])
input = micropost_params.merge(pub: @pub)
@micropost = current_user.microposts.build(input)
if @micropost.save
redirect_to :back, success: "Micropost created!"
else
render 'static_pages/home'
end
end
end
By nesting the routes, you will ensure that there is a pub_id
in the URL. You can use this to find the Pub
that this new Micropost
will belong to. In the MicropostsController
you will use the params[:pub_id]
to find the Pub
, build a Micropost
for the current_user
while adding the correct pub_id
.
With the form, you have to use an array like this [@pub, @micropost]
unless you decide to use shallow routes explained here . The array form_for
version is explained on this page just above the Setting the method header that this link takes you to.
Also, have a look at Rails nested resources and Rails shallow nested routes . When in doubt, go into the terminal and type rake routes
to see the type of routes that are exposed.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.