RAILS Как я могу создать вложенную форму для изменения has_many через логический атрибут связанного объекта с помощью флажков? - PullRequest
0 голосов
/ 30 июня 2018

У меня есть 3 модели: User, Profile и Photo.

Profile < ApplicationRecord
 belongs_to :user
 has_many :photos, through: :user

Photo < ApplicationRecord
 belongs to :user

User < ApplicationRecord
 has_one :profile
 has_many :photos

Я хотел бы создать форму для @profile, которая также отображает флажки для всех связанных с ней фотографий.

Когда фотография отмечена, я бы хотел, чтобы # featured_status этой фотографии было превращено в TRUE. (он имеет значение по умолчанию 1 в моей базе данных).

Класс фотографий имеет эти методы

class Photo < ApplicationRecord
 belongs_to :user


 has_attached_file :image, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
 validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/
 validates :image, :title, :description, presence: true

 FEATURED_STATUS = { not_featured: 0, featured: 1 }

 def featured?
  self.featured_status == FEATURED_STATUS[:featured]
 end

 def not_featured?
  self.featured_status == FEATURED_STATUS[:not_featured]
 end

 def myPhoto
  ActionController::Base.helpers.image_tag("#{image.url(:thumb)}")
 end

end

Как я могу построить эту форму?

Я пробовал разные варианты использования fields_for, collection_check_boxes, check_boxes, и я не могу правильно захватить информацию.

На данный момент это моя форма.

<%= simple_form_for @profile do |f| %>

<%= f.input :bio, input_html: { class: 'form-control'} %>

    <section class="main">
        <label>Featured Profile Photos</label>
        <% @profile.photos.each do |photo| %>
            <%= form_for ([@profile, photo]) do |f| %>
                <%= f.check_box :featured_status, :checked => (true if photo.featured?) %>
                <%= f.submit %>
                <% end %>
            <label><%= photo.myPhoto %></label>
        <% end %>
    </section>

<%= f.button :submit %>

Когда форма отображается, имеется несколько кнопок «обновить» - по одной для каждой фотографии. Я также не могу отправить изменения @ profile.bio одновременно с обновлением featured_status фотографии.

В идеале, я бы хотел, чтобы каждая из этих кнопок обновления фотографий была скрыта и просто есть одна кнопка отправки, которая обновляет текст профиля Bio: и отображает @profile.

В то же время я бы хотел, чтобы photo.featured_status был установлен в true / false, как только флажок отмечен. (Может быть, используя Javascript?)

Любые предложения действительно приветствуются.

Ответы [ 2 ]

0 голосов
/ 01 июля 2018

приложение / модели / profile.rb:

class Profile < ApplicationRecord
  has_one :user
  has_many :photos, through: :user
  accepts_nested_attributes_for :photos
end

приложение / контроллеры / profiles_controller.rb:

class ProfilesController < ApplicationController
  before_action :set_profile, only: [:update] # etc...

  def update
    if @profile.update(profile_params)
      # success, do something; i.e:
      # redirect_to @profile, notice: 'Profile has been updated'
    else
      # validation errors, do something; i.e:
      # render :edit
    end
  end

  private

  def set_profile
    @profile = Profile.find(params[:id])
  end

  def profile_params
    params.require(:profile).permit(:bio, photos_attributes: [:id, :featured_status]) # etc...
  end
end

Приложение / просмотров / профили / _form.html.erb

<%= simple_form_for @profile do |f| %>
  <%= f.input :bio, input_html: { class: 'form-control'} %>

  <section class="main">
    <label>Featured Profile Photos</label>

    <%= f.simple_fields_for :photos do |ff| %>
      <%= ff.check_box :featured_status %>
      <label><%= ff.object.myPhoto %></label>
    <% end %>
  </section>

  <%= f.button :submit %>
<% end %>

Рекомендации:

  • Подобно другим комментариям от Maxence и iGian, я бы посоветовал что-то вроде ниже:

    • Профили пользователя has_many / has_one
    • Профиль has_many Фото

    ... вместо:

    • Профиль has_one Пользователь
    • Профиль has_many Фото

    ... по той единственной причине, что, говоря интуитивно, я думаю, что пользователь (кто-то, кто входит в систему) может иметь один или несколько профилей, из которых затем профиль должен принадлежать пользователю. В настоящее время у вас есть пользователь профиля has_one, который всегда будет работать в любом случае там, где будет Foreign_key (либо пользователь, либо профиль в порядке), но я обычно делаю, чтобы узнать, где размещен ключ Foreign_key, - принять во внимание возможные будущие изменения: (т.е. has_one становится has_many), и поэтому теперь, когда я установил это, для пользователя становится более целесообразным иметь много профилей, а не для профиля много пользователей. Конечно, если вы намеренно хотите этого и знаете о реализации вашей схемы, то это всегда также правильный способ сделать это (в зависимости от ваших предварительных условий):)

Ссылки:

0 голосов
/ 01 июля 2018

в соответствии с вашими последними комментариями, я бы разработал мои отношения следующим образом:

User
has_one :profile
has_many :photos

Profile
belongs_to :user

Photo
belongs to :user 

Теперь вы можете решить, куда вы хотите включить или отключить отображение фотографий. Либо в действии «Редактирование пользователей», наряду с другими данными пользователя, либо даже данными профиля. Или, может быть, путем создания определенного действия в контроллере Photo (действие edit обычно предназначено для редактирования одного экземпляра, а не всех экземпляров для конкретного пользователя, которых должно быть несколько)

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

...