У меня были большие проблемы в течение 2 дней, и мне нужна твоя помощь !!У меня есть 2 модели: сад и резервирование (с вложенными ресурсами и использованием pundit).В «шоу» сада я хочу нажать на кнопку, которая «создает» бронирование прямо из уже созданного сада.Но мне не удается выполнить действие create, которое всегда отображает: param отсутствует или значение пусто: booking.Как сделать так, чтобы «бронирование» появлялось в параметрах и можно было звонить, например, @ booking.booker ??У вас есть решение, не удаляя require (: booking)?
Я пробовал как со страницей "new_booking", так и без нее, но безуспешно.
Большое спасибо !!
booking_controller
class BookingsController < ApplicationController
def index
end
def my_bookings
@bookings = BookingPolicy::Scope.new(current_user, Booking).scope.where(user: current_user)
end
def show
@booking.garden = @garden
end
def new
@garden = Garden.find(params[:garden_id])
@garden_id = @garden.id
@booker_id = current_user.id
@booking = Booking.new
authorize @booking
end
def create
@booking = Booking.new(booking_params)
authorize @booking
@booking.save
redirect_to root_path
end
private
def booking_params
params.require(:booking).permit(:garden_id, :booker_id)
end
end
gardens_controller
class GardensController < ApplicationController
before_action :set_garden, only: [:show, :destroy, :edit, :update ]
def new
@garden = Garden.new
authorize @garden
end
def create
@garden = Garden.new(garden_params)
authorize @garden
@garden.user = current_user
respond_to do |format|
if @garden.save
format.html { redirect_to @garden, notice: 'Garden was successfully created.' }
format.json { render :show, status: :created, location: @garden }
else
format.html { render :new }
format.json { render json: @garden.errors, status: :unprocessable_entity }
end
end
end
def index
@gardens = policy_scope(Garden)
end
def my_gardens
@gardens = GardenPolicy::Scope.new(current_user, Garden).scope.where(user: current_user)
end
def show
authorize @garden
end
def destroy
authorize @garden
@garden.destroy
respond_to do |format|
format.html { redirect_to gardens_url, notice: 'garden was successfully destroyed.' }
format.json { head :no_content }
end
end
def edit
authorize @garden
end
def update
authorize @garden
respond_to do |format|
if @garden.update(garden_params)
format.html { redirect_to @garden, notice: 'Garden was successfully updated.' }
format.json { render :show, status: :ok, location: @garden }
else
format.html { render :edit }
format.json { render json: @garden.errors, status: :unprocessable_entity }
end
end
end
private
def garden_params
params.require(:garden).permit(:title, :details, :surface, :address, :availabilities)
end
def set_garden
@garden = Garden.find(params[:id])
end
end
application_controller
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user!
include Pundit
# Pundit: white-list approach.
after_action :verify_authorized, except: [:index, :my_gardens], unless: :skip_pundit?
# after_action :verify_policy_scoped, only: [:index, :my_gardens], unless: :skip_pundit?
# Uncomment when you *really understand* Pundit!
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
def user_not_authorized
flash[:alert] = "You are not authorized to perform this action."
redirect_to(root_path)
end
private
def skip_pundit?
devise_controller? || params[:controller] =~ /(^(rails_)?admin)|(^pages$)/
end
end
pages_controller
class PagesController < ApplicationController
skip_before_action :authenticate_user!, only: [:home]
def home
end
end
application_record.rb
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
booking.rb
class Booking < ApplicationRecord
belongs_to :gardens
has_many :users, through: :gardens
end
garden.rb
class Garden < ApplicationRecord
belongs_to :user
has_many :bookings
end
user.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :gardens
has_many :bookings, through: :gardens
end
application_policy.rb
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
@user = user
@record = record
end
def index?
false
end
def my_gardens?
false
end
def show?
scope.where(:id => record.id).exists?
end
def create?
false
end
def new?
create?
end
def update?
false
end
def edit?
update?
end
def destroy?
false
end
def scope
Pundit.policy_scope!(user, record.class)
end
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
scope
end
end
end
booking_policy.rb
class BookingPolicy < ApplicationPolicy
class Scope < Scope
def resolve
scope.all
end
end
def create?
true
end
def update?
user_is_the_owner_or_admin?
end
def destroy?
user_is_the_owner_or_admin?
end
def index?
true
end
def show
scope.where(:id => record.id).exists?
end
private
def user_is_the_owner_or_admin?
user.admin || record.booker == user
end
end
garden_policy.rb
class GardenPolicy < ApplicationPolicy
class Scope < Scope
def resolve
scope.all #>> permet d'afficher tous les restos dans index
end
end
def create?
true
end
def update?
user_is_the_owner_or_admin?
end
def destroy?
user_is_the_owner_or_admin?
end
def index?
true
end
def show
scope.where(:id => record.id).exists?
end
private
def user_is_the_owner_or_admin?
user.admin || record.user == user
end
end
new_booking.html.erb
<h1>My booking</h1>
<%= simple_form_for [@garden, @booking] do |f| %>
<%= f.input :booker_id, disabled:true %>
<%= f.input :garden_id, disabled:true %>
<%= f.button :submit %>
<% end %>
show_garden.html.erb
<h1>My Garden</h1>
<ul>
<li>Title : <%= @garden.title %></li>
<li>Address : <%= @garden.address %></li>
<li>Details : <%= @garden.details %></li>
<li>Surface : <%= @garden.surface %></li>
<p> Here will appear the availabilities to select</p>
<% if policy(@garden).destroy? %>
<li><%= link_to "Delete" %> //
<% end %>
<% if policy(@garden).edit? %>
<%= link_to "Edit" %></li>
<% end %>
<li><%= link_to "home", gardens_path %></li>
<li><%= link_to "My gardens", my_gardens_path %></li>
<li><%= link_to "Book the Garden", new_garden_booking_path(@garden) %></li>
</ul>
rout.rb
Rails.application.routes.draw do
devise_for :users
delete 'gardens/:id', to: "gardens#destroy", as: :delete_garden
resources :gardens, except: [:delete] do
resources :bookings, only: [:new, :create, :show]
end
get "my_gardens", to: "gardens#my_gardens", as: :my_gardens
root to: 'pages#home'
end