2014-11-05 2 views
1

Я использую самоцвет скрепки.Загрузка изображений через другое изображение

class Business < ActiveRecord::Base 
    has_many :images, :as => :imageable 
    has_many :reviews 
end 

class Image < ActiveRecord::Base 
    belongs_to :imageable, :polymorphic => true 
    has_attached_file :photo 
end 

class Review < ActiveRecord::Base 
    belongs_to :business 
    has_many :images, :as => :imageable 
end 

images/_form.html.erb Это работает: контроллер

<%= form_for @image do |f| %> 
    <%= f.fields_for :photos_attributes do |photo| %> 
    <%= photo.file_field :image, :multiple => false %> 
    <% end %> 
    <%= f.submit 'Save' %> 
<% end %> 

Изображение:

def create 
    @image = @business.images.new(image_params) 
    if @image.save 
    flash[:success] = "Image uploaded!" 
    redirect_to root_url 
    else 
    render 'new' 
    end 
end 

Я хочу, чтобы иметь возможность загружать изображения также с отзывами. Я имею в виду что-то вроде этого:

<%= form_for @review do |f| %> 
    <%= f.text_area :content %> 
    <%= f.fields_for :photos_attributes do |photo| %> 
    <%= photo.file_field :image, :multiple => false %> 
    <% end %> 
    <%= f.submit 'Submit Review with Image'%> 
<% end %> 

Как бы мой обзор контроллера взгляд, так как изображения от модели изображения, а остальное от модели обзора?

+0

Вы пробовали с вложенными атрибутами: http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html – Albin

+0

Я предполагаю, что ваш класс обзора 'has_one: image' или что-то подобное? – Albin

+0

Какова связь моделей изображений и обзоров? –

ответ

2

Так я бы заложить его, как это -

Модели

class Business < ActiveRecord::Base 

    has_many :images, :as => :imageable 
    has_many :reviews 

end 

class Image < ActiveRecord::Base 

    belongs_to :imageable, :polymorphic => true 

end 

class Review < ActiveRecord::Base 

    belongs_to :business 
    has_many :images, :as => :imageable 

    accepts_nested_attributes_for :images 

end 

Я добавил в accepts_nested_attributes_for :images потому, что вам нужно, чтобы ваш контроллер Обзор сохранить изображение при его сохранении себя , Я не уверен, как у вас настроен контроллер Business, но я бы посоветовал сделать это так же, как яснее и понятнее.

Обзор Вид - Форма выпуска

<%= form_for @review do |f| %> 
    <%= f.text_area :content %> 
    <%= f.fields_for :images do |photo| %> 
     <%= photo.file_field :photo, :multiple => false %> 
    <% end %> 
    <%= f.submit 'Submit Review with Image'%> 
<% end %> 

Я немного изменил форму, чтобы позволить accepts_nested_attributes_for :images работать лучше.

Наконец Обзор контроллера

Обзор Контроллер

class ReviewsController < ApplicationController 


    def new 

    @review = Review.new 
    @review.images.build 

    end 

    def create 

    @business = Business.find(id_of_business_your_reviewing) 
    @review = @business.reviews.build(review_params) 

    if @review.save 

     puts "Saved" 
     redirect_to "path" 
    else 

     puts "Something failed" 
     render 'new' 

    end 

    end 

private 

    def review_params 

    params.require(:review).permit(:content, :images_attributes => [:id, :photo]) 

    end 

end 

Это позволит создать новый обзор и добавить фотографию к нему через изображения. Нет необходимости обращаться к Image Controller, поскольку у Обзора есть доступ к нему и может принимать его атрибуты.

Я бы предложил реализовать что-то похожее на бизнес-модель, когда вы создаете/редактируете предприятия. Я бы выполнил эти действия с бизнес-контроллером и использовал accepts_nested_attributes_for :images, чтобы он мог принимать его атрибуты.

Надеюсь, что это поможет ответить на ваш вопрос. Дайте мне знать, если я не объясню что-то должным образом.

1

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

Хорошая конструкция заключается в использовании полиморфной ассоциации для модели изображения.

class Business < ActiveRecord::Base 
has_many :images, as: :parent 
has_many :reviews 
end 

class Image < ActiveRecord::Base 
belongs_to :parent, polymorphic: true 
has_attached_file :photo 
end 

class Review < ActiveRecord::Base 
has_many :images, as: :parent 
belongs_to :business 
end 

и использовать один из двух возможных решений я предложить в случае 1. Следует отметить, что № 2 лучше.

Проверьте this link, если вы не знаете, как построить полиморфные ассоциации.


Случай 1 Для моделей, которые имеют отношение, как бизнес-модели ::

вы можете:

1 - Добавить новое действие в business_controller, чтобы добавить изображение как ваш код, используя форму, которую вы уже писали в вопросе для изображения, но с указанием пути к действию. Форма должна иметь заголовок, как

form_for @image, :url => whatever_path_to_the_action 

или

2 - Использование accept_nested_attributes в модели и использовать новые и редактировать действия, которые у вас уже есть в business_controller без дополнительного кода и изображения будут сохранены в бизнесе независимо от того, является ли он новым, или если вы просто отредактируете его, чтобы добавить новые изображения, а во взглядах используйте fields_for.

видеть эту ссылку, если вы не знакомы сaccept_nested_attributes, а также это this для построения ваших форм.

  • То же относится к рассмотрению, если вы следовали предложенному дизайну.

Для моделей, которые не имеют никакого отношения, как обзор модель в вашем дизайне ::

вы можете добавить действие в reviews_controller add_image.

def add_image 
    @image = @review.business.images.new(image_params) 
    if @image.save 
    flash[:success] = "Image uploaded!" 
    redirect_to root_url 
    else 
    render 'YOUR FORM' 
    end 
end 

<%= form_for @image, url: path_to_the_action_add_image do |f| %> 
    <%= f.file_field :photo %> 
    <%= f.text_area :content %> 
    <%= f.submit 'Submit Review'%> 
<% end %> 

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

1

Если вы хотите добавить изображение с обзором. У вас должно быть какое-то отношение между ними. Я добавил has_one отношение. Это идеально подходит для вашего состояния. Вы также можете добавить has_many. Ваша модель должна выглядеть следующим образом:

class Business < ActiveRecord::Base 
has_many :images 
has_many :reviews 
end 

class Image < ActiveRecord::Base 
belongs_to :business 
belongs_to :review 
has_attached_file :photo 
end 

class Review < ActiveRecord::Base 
has_one :image 
belongs_to :business 
end 

Ваша форма должна выглядеть следующим образом:

<%= form_for @review do |f| %> 
    <%= f.text_area :content %> 
    <%= fields_for :image do |i| %> 
    <%= i.file_field :photo %> 
    <% end %> 
    <%= f.submit 'Submit Review'%> 
<% end %> 

При использовании реек 4. Изменения требуют в контроллере:

def create 
    @review = Review.create(review_params) #This will create photo as well 
    redirect_to xyz_path 
end 

private 

    def review_params 
    params.require(:review).permit(:content, images_attributes: [:id, :photo, :_destroy]) 
    end 

Вам нужно добавьте изменения базы данных. Поэтому внесите соответствующие изменения. (Добавить review_id в вашей фотографии)

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

+0

Спасибо Nitin. Кажется, это не работает. Я не понимаю строку: 'tasks_attributes: [: id,: photo,: _destroy]' В какой момент я действительно сохраняю изображение? – Bruno

+0

Извините, что я ошибся. Это должно быть 'images_attributes', я обновил свой ответ. –

Смежные вопросы