简体   繁体   中英

How to get the id from the URL Rails

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:

routes.rb

Rails.application.routes.draw do
  resources :micropost
  resources :pub do
    resources :micropost
  end
end

_micropost_form.html.erb

<%= form_for([@pub, @micropost]) do |f| %>

microposts_controller.rb

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM