Rails:通过link_to 动作创建和销毁belongs_to 关联
Rails: create and destroy belongs_to association through link_to actions
我正在开发一个管理界面,其中有图像和英雄。英雄 table 仅包含两列:id 和 image_id。我希望能够为英雄添加和删除图像 table。
我有一个 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
操作。
跟进你对你的最后评论 add_to_action,我想在下面提出解决方案
Select_to_hero.html.erb,更改 :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
感谢总是乐于助人的@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 中的一个条目来删除英雄声明。
感谢大家的建议。
我正在开发一个管理界面,其中有图像和英雄。英雄 table 仅包含两列:id 和 image_id。我希望能够为英雄添加和删除图像 table。
我有一个 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
操作。
跟进你对你的最后评论 add_to_action,我想在下面提出解决方案
Select_to_hero.html.erb,更改 :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
感谢总是乐于助人的@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 中的一个条目来删除英雄声明。
感谢大家的建议。