简体   繁体   中英

How should I update a resource that is fully depend on other resource

Let's say I have those two models:

class Post < ApplicationRecord
  belongs_to :site
end

class Site < ApplicationRecord
  has_many :posts
end

In order to create a post, I need to know the site id. Right now I have a route that points to PostsController#create :

post 'posts', to: 'posts#update'

Should I expect the user to send the site_id in the body of the request?

# config/routes.rb
resources :sites do
  resources :posts
end

This creates nested routes . Run $ rails routes to see the routes created.

Should I expect the user to send the site_id in the body of the request?

No. A nested route describes the relationship between the two resources. Its very obvious by looking at the path that POST /sites/1/posts will create a post belonging to a site.

It would be ok to pass a site id in the params if you are using shallow nesting and the user can change which site a post belongs to when updating.

# app/controllers/posts_controller.rb
class PostsController
  before_action :set_site
  before_action :set_post, only: [:show, :edit, :update]

  # GET /sites/1/posts/1
  def show
  end

  # GET /sites/1/posts
  def index
    @posts = @site.posts
  end

  # GET /sites/1/posts/new
  def new
    @post = @site.posts.new
  end

  # POST /sites/1/posts
  def create
    @post = @site.posts.new(post_params)
    if @post.save
      redirect_to @post
    else
      render :new
    end
  end

  # PATCH|PUT /sites/1/posts
  def update
    if @post.update(post_params)
      redirect_to @post
    else
      render :edit
    end
  end

  # GET /sites/1/posts/edit
  def edit
  end

  private
  def set_site
    @site = Site.includes(:posts).find(params[:site_id])
  end

  def set_post
    @post = @site.posts.find(params[:id])
  end

  def post_params
    params.require(:post).permit(:title) # ...
  end
end
# app/views/posts/_form.html.erb
<%= form_for [@site, @post] do |f| %>
  # ...
<% end %>

# app/views/posts/new.html.erb
<%= render partial: 'form' %>

# app/views/posts/edit.html.erb
<%= render partial: 'form' %>

When you put on your route resources: posts that creates the automatic routes to index, show, create, update and delete. post 'posts' should point to 'posts#create'. put 'posts' points to 'posts#update'.

And yes, send the site_id in the body of the request

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