0

我有 3 个模型UserProfilePhoto

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 %>

当表单呈现时,有多个“更新”按钮 - 每张照片一个。我也无法在更新照片的 features_status 的同时提交 @profile.bio 更改。

理想情况下,我希望隐藏这些照片更新按钮中的每一个,并且只有一个提交按钮来更新个人资料 bio:text 并呈现@profile。

同时,我希望 photo.featured_status 在复选框被标记后立即变为真/假。(也许使用Javascript?)

任何建议都非常感谢。

4

2 回答 2

0

应用程序/模型/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

app/views/profiles/_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),因此现在我建立了这一点,用户拥有许多个人资料而不是个人资料拥有许多用户更有意义。当然,如果您有意以这种方式想要它并且知道您的架构实现,那么它始终也是一种正确的方法(取决于您的先决条件):)

参考:

于 2018-07-01T01:11:01.503 回答
0

根据你最后的评论,我会这样设计我的关系:

User
has_one :profile
has_many :photos

Profile
belongs_to :user

Photo
belongs to :user 

现在您可以决定在哪里打开/关闭编辑照片显示。在用户编辑操作中,与其他用户数据一起,甚至是配置文件数据。或者可能通过在 Photo 控制器中创建特定操作(编辑操作通常用于编辑单个实例,而不是特定用户的所有实例,这应该是几个)

然后,如果您有实际的代码和视图,则可以走得更远。

于 2018-06-30T23:20:59.543 回答