为什么has_one与嵌套路由的关联可以访问url搜索栏中所有可能的路由?

时间:2017-02-03 18:30:43

标签: ruby-on-rails associations has-one

我对你可以获得每个网址的方式感到困惑,例如deal /:id / properties /:id尽管有交易和财产的一对一关联。为什么我可以在与交易2相关联的属性是我的数据库中的属性6时在浏览器URL中输入和获得交易/ 2 / properties / 14(或任何组合)。我在视图中的链接确实有效,我使用链接获得正确的关联交易/ 2 / properties / 6但我的问题是我在设置(或其他任何地方)做错了或只是Rails允许每一个可能组合将在浏览器中进行测试....如果是,是否有办法防止这种情况发生?非常感谢

我有一对一的关联=> 1交易has_one属性和属性belongs_to交易。我有嵌套路线如下

    resources :deals, only: [:index, :show, :create, :update, :destroy] do
      scope '/siteadmin' do
        resources :properties
      end
    end

    scope '/siteadmin' do
      resources :deals, except: [:index, :show]
    end

deal.rb

    class Deal < ApplicationRecord
      has_one :property, dependent: :destroy
      accepts_nested_attributes_for :property
    end

property.rb

    class Property < ApplicationRecord
      belongs_to :deal
      validates :full_address, presence: true
      validates_uniqueness_of :deal_id
    end

deals_controller.rb

      class DealsController < ApplicationController
      before_action :set_deal, only: [:show, :edit, :update, :destroy]
      def index
        @deals = Deal.all
      end
      def show
        @property = @deal.property
      end
      def new
        @deal = Deal.new
      end
      def create
        @deal = Deal.new(deal_params)
        if @deal.save
          redirect_to deals_path, notice: 'Deal was successfully created'
        else
        render :new
        end
      end
      def edit
      end
      def update
        if @deal.update(deal_params)
          redirect_to @deal, notice: 'Deal was successfully updated'
        else
          flash.now[:alert] = "Deal has not been updated."
          render :edit
        end
      end
      def destroy
        @deal.destroy
        redirect_to deals_path, notice: 'Deal was successfully deleted'
      end

      private
      def deal_params
        params.require(:deal).permit(:description, :kind, :address, :image_url, :occupancy, :yield)
      end
      def set_deal
        @deal = Deal.find(params[:id])
      rescue ActiveRecord::RecordNotFound
        flash[:alert] = "The deal you were looking for could not be found."
        redirect_to deals_path
      end
    end

properties_controller.rb

    class PropertiesController < ApplicationController
    before_action :set_deal
    before_action :set_property, only: [:show, :edit, :update, :destroy]

    def index
      @properties = Property.all.order(id: :asc)
    end

    def show
    end

    def new
      @property = @deal.build_property
    end
    def create
      @property = @deal.build_property(property_params)
      if @property.save
        flash[:notice] = "Property has been created."
        redirect_to [@deal, @property]
      else
        flash.now[:alert] = "Property has not been created."
        render "new"
      end
    end
    def edit
    end

    def update
      if @property.update(property_params)
        flash[:notice] = "Property has been updated."
        redirect_to [@deal, @property]
      else
        flash.now[:alert] = "Property has not been updated."
        render "edit"
      end
    end
    def destroy
      @property.destroy
      flash[:notice] = "Property has been deleted."
      redirect_to @deal
    end
    private
    def property_params
      params.require(:property).permit(:genre, :surface, :nb_rooms, :nb_bedrooms, :city, :district, :full_address)
    end
    def set_property
      @property = Property.find(params[:id])
    end
    def set_deal
      @deal = Deal.find(params[:deal_id])
    end
  end

处理show.html.erb

<h2>Property in the deal:</h2>
<ul class="list-unstyled text-justify">
  <li>Property id #<%= @deal.property.try(:id) %> - <%= link_to @deal.property.try(:full_address), [@deal, @property] %></li>
  <li>Adresse of the property: <%= @deal.property.try(:full_address) %></li>
  <li><%= link_to "see all the properties", deal_properties_path(@deal) %></li>
  <%= link_to "add deal", new_deal_path, {class: "btn btn-primary"} %>
</ul>

属性index.html.erb

      <header>
      <h2>All properties</h2>
      <ul id="properties in the db">
      <% @properties.each do |property| %>
      <li>Property id #<%= property.id %> - <%= link_to property.full_address, deal_property_path(property.deal, property) %></li>
      <li><%= link_to "See our Deal", deal_path(property.deal) %></li>
      <li><%= link_to "Edit Property", edit_deal_property_path(property.deal, property) %></li>
      <li>Deal id #<%= property.deal.id %></li>
      <% end %>
      <br>
      </ul>
      <ul class="actions">
        <li><%= link_to "Add Property", new_deal_property_path(@deal),
          class: "new" %></li>
        <li><%= link_to "Back to deals", deals_path%></li>
      </ul>
    </header>

属性show.html.erb

   <header>
   <h2>Property id #<%= @property.id %> <%= @property.full_address %></h2>
   </header>
   <h3>This is the property #<%= @property.id %> of the Deal @<%= @deal.id %> - <%= @deal.address %></h3>
   <p>This property is located at <%= @property.full_address %></p>
   <li><%= link_to "See all the properties", deal_properties_path(@deal)%></li>

1 个答案:

答案 0 :(得分:0)

路由只处理查询字符串的格式而不处理其中的值。

我喜欢做的是将数据范围放在控制器中,就像这样

    class PropertiesController < ApplicationController
    before_action :set_deal
    before_action :set_property, only: [:show, :edit, :update, :destroy]

    def index
      @properties = Property.all.order(id: :asc)
    end

    def show
    end

    def new
      @property = @deal.build_property
    end
    def create
      @property = @deal.build_property(property_params)
      if @property.save
        flash[:notice] = "Property has been created."
        redirect_to [@deal, @property]
      else
        flash.now[:alert] = "Property has not been created."
        render "new"
      end
    end
    def edit
    end

    def update
      if @property.update(property_params)
        flash[:notice] = "Property has been updated."
        redirect_to [@deal, @property]
      else
        flash.now[:alert] = "Property has not been updated."
        render "edit"
      end
    end
    def destroy
      @property.destroy
      flash[:notice] = "Property has been deleted."
      redirect_to @deal
    end
    private
    def property_params
      params.require(:property).permit(:genre, :surface, :nb_rooms, :nb_bedrooms, :city, :district, :full_address)
    end
    def set_property
      @property = @deal.property #.find(params[:id]) # you don't need to find it because there is only 1
    end
    def set_deal
      @deal = Deal.find(params[:deal_id])
    end
  end