Rails: создайте и уничтожьте ассоциацию own_to с помощью действий link_to - PullRequest
0 голосов
/ 31 января 2019

Я работаю над интерфейсом администратора, где у меня есть изображения и герои.Таблица героев состоит только из двух столбцов: id и image_id.Я хотел бы иметь возможность добавлять и удалять изображения в таблице героев.

У меня есть действие и просмотр для героев select_to_hero и select_from, которые отображают либо все изображения, которые еще не подключены, либо все существующие герои, и оба работают, ноДействия add_to_hero и remove_from_hero, которые я использую для создания новой или уничтожения существующей ассоциации, не работают.

Модель Hero.rb

class Hero < ActiveRecord::Base
  attr_accessible :image_id
  belongs_to :image
end

Image.rb Модель

class Image < ActiveRecord::Base
  attr_accessible :alt, :author, :copyright, :file_name, :title
  has_one :hero
  mount_uploader :file_name, ImageUploader
end

Select_from_hero.html.erb

<% @heroes.each do |hero| %>
  <%= link_to(image_tag(hero.image.file_name.url(:thumb), {:action => 'remove_from_hero', :id => hero, :hero => @hero}) %>
<% end %>

Select_to_hero.html.erb

<% @images.each do |image| %>
  <%= link_to(image_tag(image.file_name.url(:thumb), {:action => 'add_to_hero', :id => image, :hero => @hero}) %>
<% end %>

images_controller.rb

def add_to_hero
  @hero.image << Image.find(params[:id]) unless @hero.image.include?(Image.find(params[:id]))
  if @hero.save
    ..
  else
    render :action => 'select_to_hero'
  end
end

def remove_from_hero
  @hero.image.delete(Image.find(params[:id]))
  if @hero.save
    ..
  else
    render :action => 'select_from_hero'
  end
end

С этим параметром я получаю:

NoMethodError in Admin::ImagesController#add_to_hero
undefined method `image' for nil:NilClass

и

NoMethodError in Admin::ImagesController#remove_from_hero
undefined method `image' for nil:NilClass

Но я могу запросить существующую ассоциацию:

> Hero.find(2).image
  Hero Load (0.3ms)  SELECT `heroes`.* FROM `heroes` WHERE `heroes`.`id` = ? LIMIT 1  [["id", 2]]
  Image Load (0.3ms)  SELECT `images`.* FROM `images` WHERE `images`.`id` = 1 LIMIT 1
 => #<Image id: 1, file_name: "red.jpg", title: "blu", alt: "yellow", author: "John", copyright: "Jane", created_at: "2019-01-29 19:50:25", updated_at: "2019-01-29 19:50:25"> 

Как мне это работает?

Обновление

Маршруты

namespace :admin do
  resources :heroes
  match '/images/select_to_hero',        :to => 'images#select_to_hero',    :as => :select_to_hero
  match '/images/select_from_hero',      :to => 'images#select_from_hero',  :as => :select_from_hero
  resources :images
  match '/images/add_to_hero/:id',       :to => 'images#add_to_hero',       :as => :add_to_hero
  match '/images/remove_from_hero/:id',  :to => 'images#remove_from_hero',  :as => :remove_from_hero
  ...
end

Мне пришлось переместить маршруты select_to_hero и select_from_hero выше resources :images, иначе вызов вызвал бы действие show.

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Благодаря всегда полезному @vasilisa я нашел способ решить мою проблему.Мне пришлось использовать:

<% @images.each do |image| %>
  <%= link_to(image_tag(image.file_name.url(:thumb)), {:action => 'add_to_hero', :id => image, :image_id => image}) %>
<% end %>

в моем представлении и:

def add_to_hero
  @hero = Hero.new(:image_id => params[:id])

  if @hero.save
    ...
  else
    render :action => 'select_to_hero'
  end
end

в моем действии контроллера.

Это работает, поскольку в моем случае мне нужно было только объявить изображение героя, создав новую запись в Hero, или удалить объявление героя, уничтожив запись в Hero.

Спасибовсе за их советы.

0 голосов
/ 31 января 2019

следите за вашим последним комментарием о вашей add_to_action, я хотел бы предложить решение ниже

Select_to_hero.html.erb, change: hero и отправить только id героя, как показано ниже

    <% @images.each do |image| %>
      <%= link_to(image_tag(image.file_name.url(:thumb), {:action => 'add_to_hero', :id => image, :hero_id => @hero.id}) %>
    <% end %>

images_controller.rb, сначала найдите героя из hero_id

    def add_to_hero
      @hero = Hero.find(params[:hero_id])
      @hero.image << Image.find(params[:id]) unless @hero.image.include?(Image.find(params[:id]))
      if @hero.save
        ..
      else
        render :action => 'select_to_hero'
      end
    end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...