#ruby-on-rails #model-view-controller #ruby-on-rails-5
#ruby-on-rails #модель-представление-контроллер #ruby-on-rails-5
Вопрос:
Я ищу ссылку, позволяющую пользователю отменить закрепленный твит.
Мое мнение
<% if tweet.pin? %>
<%= link_to '<i class="fas fa-thumbtack"></i> Unpin'.html_safe, pin_tweet_path(tweet), :method =>
:put, class: "dropdown-item" %>
<% else %>
<%= link_to '<i class="fas fa-thumbtack"></i> Pin to your profile'.html_safe, pin_tweet_path(tweet),
:method => :put, class: "dropdown-item" %>
<% end %>
Моя модель (tweet.rb)
belongs_to :user, optional: true
scope :pin, -> { where(pin:true) }
scope :no_pin, -> (id) { where.not(id: id) if id }
after_save :ensure_only_one_pinned_tweet
private
def ensure_only_one_pinned_tweet
user.tweets.pin.no_pin(id).update_all(pin: false) if pin?
end
Мой метод контроллера
def pin
@tweet = Tweet.find(params[:id])
if @tweet.update(pin: true)
redirect_to user_path(current_user.id)
else
@tweet.update(pin: false)
redirect_to user_path(current_user.id)
end
end
Мой маршрут
resources :tweets do
member do
put :pin
end
end
Эта настройка позволяет автоматически заменять каждый pin-код при выборе пользователем другого pin-кода, тем самым одновременно используя только один pin-код. Это работает нормально.
Но я хочу включить возможность для пользователя также отменить закрепление и, следовательно, не иметь выводов.
Какой самый простой способ сделать это? ty
Обновить
Обновление с помощью pin-контроллера
resources :tweets do
...
resources :pins
...
end
Маршруты
tweet_pins GET /tweets/:tweet_id/pins(.:format) pins#index
POST /tweets/:tweet_id/pins(.:format) pins#create
new_tweet_pin GET /tweets/:tweet_id/pins/new(.:format) pins#new
edit_tweet_pin GET /tweets/:tweet_id/pins/:id/edit(.:format) pins#edit
tweet_pin GET /tweets/:tweet_id/pins/:id(.:format) pins#show
PATCH /tweets/:tweet_id/pins/:id(.:format) pins#update
PUT /tweets/:tweet_id/pins/:id(.:format) pins#update
DELETE /tweets/:tweet_id/pins/:id(.:format) pins#destroy
Вид
<% if tweet.pin? %>
<%= link_to '<i class="fas fa-thumbtack"></i> Unpin'.html_safe, tweet_pin_path(tweet), method: :patch, class: "dropdown-item" %>
<% else %>
<%= link_to '<i class="fas fa-thumbtack"></i> Pin to your profile'.html_safe, tweet_pin_path(tweet), method: :patch, class: "dropdown-item" %>
<% end %>
Ошибка
No route matches {:action=>"show", :controller=>"pins", :tweet_id=>#<Tweet id: 18, user_id: 2, content: "Pin test", created_at: "2020-11-23 15:15:03", updated_at: "2020-11-23 15:22:39", retweet_id: nil, pin: nil>}, missing required keys: [:id]
Ответ №1:
Одна из моих самых любимых статей в блоге — как DHH организует свои контроллеры Rails. Итак, имея это в виду, мне интересно, почему у вас есть pins
действие. Я думаю, ваша жизнь была бы намного проще, если бы у вас был просто TweetsController#update
или, может быть, даже Tweet::PinsController
если у вас больше функциональности. С помощью функции обновления вы можете просто принять значение pins
атрибута вместо того, чтобы устанавливать для него значение true.
class PinsController
def update
@tweet = Tweet.find(params[:id])
if @tweet.update(pin: params[:pin])
flash[:success] = 'Pinned tweet!'
redirect_to user_path(current_user.id)
else
flash[:error] = 'Ups, something went wrong here!'
redirect_to user_path(current_user.id)
end
end
end
Затем просто обновите свои маршруты и представления, чтобы использовать update
маршрут, и все должно быть в порядке. Обновление кода модели не требуется.
Комментарии:
1. привет, Тай, как будет выглядеть маршрутизация для нового контроллера контактов? Я использую ресурсы: контакты в моей маршрутизации и исправление на мой взгляд, но он продолжает пытаться перейти к действию show.
2. Пожалуйста, взгляните на руководство по маршрутизации Rails guides.rubyonrails.org/routing.html . Я почти уверен, что эту ошибку можно легко исправить, проведя некоторое исследование того, как на самом деле работает маршрутизация 😉