1

我有一个系统设置,用户可以在其中发布微博(基本上是状态更新)并上传照片以与微博一起使用。

我有:

微博模型(has_one photo) Photo_album 模型(has_many photos) 照片模型(belongs_to micropost, belongs_to photo_album)

用户在文本区域中填写文本并选择一张照片。提交后,微博表会使用微博相关数据(例如内容、created_at 等)进行更新。

同时,我希望我的照片表(照片模型)更新为用户选择的照片但正确的相册。如果您看下面,您可以在我的 users_controller 中看到实例变量 @photo 的值。这样可以确保上传的照片链接到名为“微博相册”的正确相册。它的目的是链接到所有与微博相关的照片。

我有一个用户控制器:

  def new
     @user = User.new 
     @micropost = Micropost.new(:user_id => users_id)
     @photo = Photo.new(:photo_album_id => PhotoAlbum.where(:user_id => current_user.id, :album_title => "microposts album").first.id)
  end

根据我之前提出的问题,确定我需要使用accepts_nested_attributes_for、fields_for 以便能够使用一种形式更新多个模型。这就是我设置的方式。

微贴模型:

class Micropost < ActiveRecord::Base

  belongs_to :user
  has_one  :photo
  accepts_nested_attributes_for :photo
  attr_accessible :content, :user_id, :poster_id, :username, :image, :remote_image_url

end

照片模型:

class Photo < ActiveRecord::Base

  belongs_to :photo_album

    attr_accessible :photo_album_id, :photo_title, :image, :remote_image_url
    mount_uploader :image, ImageUploader

end

最后是微博表格:

= form_for @micropost, :remote => true do |f|
    = f.fields_for @photo do |p|
        = p.file_field :image
    = f.hidden_field :user_id
    = f.text_area :content
    = f.submit "Post"

起初我得到了错误:

ActiveModel::MassAssignmentSecurity::Error (Can't mass-assign protected attributes: photo):

我有点困惑,因为我认为属性是自动分配的。至少这就是我在文档中读到的内容。无论如何,我继续将 :photo 添加到 micropost 模型 attr_accessible 白名单中。

第一个错误发生了,然后我得到了这个:

ActiveRecord::AssociationTypeMismatch (Photo(#2169424320) expected, got ActiveSupport::HashWithIndifferentAccess(#2157396720)):

也许我误解了这个功能是如何工作的,但我已经通读了这个并且还查看了 3.2.3 api 文档,但不是我哪里出错了。

我真的很感激一些帮助,让这个工作。

在此先感谢,我希望这篇长篇文章不受欢迎。只是想提供所有这些信息会让人们了解我正在努力做得更好。

亲切的问候

更新: 使用 :photo_attributes 而不是照片会给我以下错误:

Started POST "/microposts" for 127.0.0.1 at 2012-05-10 21:01:11 +0100
[02b23327ad83000f75c418d8739e7f49] [127.0.0.1] Processing by MicropostsController#create as JS
[02b23327ad83000f75c418d8739e7f49] [127.0.0.1]   Parameters: {"micropost"=>{"photo"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x00000102c293d8 @original_filename="7seriesbmw.jpeg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"micropost[photo][image]\"; filename=\"7seriesbmw.jpeg\"\r\nContent-Type: image/jpeg\r\n", @tempfile=#<File:/var/folders/fh/fhADKPjGG8qSuCeoHCTNYE+++TI/-Tmp-/RackMultipart20120510-14787-1e1mrhh>>}, "user_id"=>"2", "content"=>"ioo"}, "commit"=>"Post", "utf8"=>"✓", "authenticity_token"=>"/y8Lr+e7xgabt60GWxnMGvCtIi7IjqrYDoA84vAqYcE=", "remotipart_submitted"=>"true", "X-Requested-With"=>"IFrame", "X-Http-Accept"=>"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01"}
[02b23327ad83000f75c418d8739e7f49] [127.0.0.1]   User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
[02b23327ad83000f75c418d8739e7f49] [127.0.0.1] Completed 500 Internal Server Error in 649ms
[02b23327ad83000f75c418d8739e7f49] [127.0.0.1] 
ActiveModel::MassAssignmentSecurity::Error (Can't mass-assign protected attributes: photo):
  app/controllers/microposts_controller.rb:9:in `create'

将 attr_accessor 改回 :photo 而不是 :photo_attributes 后:

Started POST "/microposts" for 127.0.0.1 at 2012-05-10 21:20:07 +0100
[985e0f204bf7ffac1f7c02fbec35ad9b] [127.0.0.1] Processing by MicropostsController#create as JS
[985e0f204bf7ffac1f7c02fbec35ad9b] [127.0.0.1]   Parameters: {"micropost"=>{"photo"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x00000102f8a3b0 @original_filename="7seriesbmw.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"micropost[photo][image]\"; filename=\"7seriesbmw.png\"\r\nContent-Type: image/png\r\n", @tempfile=#<File:/var/folders/fh/fhADKPjGG8qSuCeoHCTNYE+++TI/-Tmp-/RackMultipart20120510-15197-9rt2xn>>}, "user_id"=>"2", "content"=>"pp"}, "commit"=>"Post", "utf8"=>"✓", "authenticity_token"=>"/y8Lr+e7xgabt60GWxnMGvCtIi7IjqrYDoA84vAqYcE=", "remotipart_submitted"=>"true", "X-Requested-With"=>"IFrame", "X-Http-Accept"=>"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01"}
[985e0f204bf7ffac1f7c02fbec35ad9b] [127.0.0.1]   User Load (0.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
[985e0f204bf7ffac1f7c02fbec35ad9b] [127.0.0.1] Completed 500 Internal Server Error in 452ms
[985e0f204bf7ffac1f7c02fbec35ad9b] [127.0.0.1] 
ActiveRecord::AssociationTypeMismatch (Photo(#2180069640) expected, got ActiveSupport::HashWithIndifferentAccess(#2153916820)):
  app/controllers/microposts_controller.rb:9:in `create'

Microposts 控制器创建动作:

def create


    if params[:micropost][:user_id].to_i == current_user.id
     @micropost = current_user.microposts.build(params[:micropost])

     @comment = Comment.new(:user_id => current_user.id)
        respond_to do |format|
            if @micropost.save


            format.js   { render :post_on_springboard }

            end
        end
    else

    user = User.find_by_username(params[:micropost][:username])
    @micropost = user.microposts.build(params[:micropost])
    if @micropost.save

    UserMailer.new_wall_post_notification(user, current_user).deliver if user.email_notification == 1

    flash[:success] = "Micropost posted"
    redirect_to root_path+user.username
    else
    flash[:error] = "#{@micropost.errors.full_messages.first}"
    redirect_to root_path+user.username
    end

    end

end
4

4 回答 4

1

您尝试做的很多事情都与关系有关,并且您应该能够让 Rails 约定为您工作。如果您开始使用rails 编写一些相当简单的代码,这通常是一个不好的迹象。

实际上,我会首先关注您的路线。

例如,如果您将照片嵌套在相册中,例如

resources :albums do
  resources :photos
end

然后你会得到很多你想要的路径和功能。

form_for [@album, @post]确保您的表格使用与您的表格一起使用的东西accepts_nested_attributes_for

于 2012-05-10T22:54:23.577 回答
0

尝试将 :photo_attributes 添加到您的 micropost 模型中的 attar_accessible 列表中

我认为这应该解决第一个错误。

还在看第二个。

您能否从表单中发布完整的堆栈跟踪,这可能是您的控制器方法的问题。

于 2012-05-10T19:41:57.900 回答
0

改变

f.fields_for @photo 

f.fields_for :photo 

并添加

@micropost.build_photo(:photo_album_id => :photo_album_id => current_user.photo_albums.find_by_album_title("microposts album").id) 

到我的 microposts_controller 解决了我的问题

于 2012-05-11T13:18:25.730 回答
0
class Organization < ActiveRecord::Base

  has_one :picture, :dependent => :destroy
  accepts_nested_attributes_for :picture

  attr_accessible :address, :contect_number, :email, :name, :type_of_organization, :picture_attributes
end


class Picture < ActiveRecord::Base
  belongs_to :organization
  mount_uploader :avatar, AvatarUploader
  attr_accessible :avatar, :organization_id
end


class OrganizationsController < ApplicationController
  load_and_authorize_resource

  def new
    @organization = Organization.new
    # @organization.attributes = Picture.new
    # @picture = Picture.new
  end

  def create
    logger.info "++++++++inside the organisation controller++++++++++"
    logger.info params[:organization].inspect

    @org = Organization.new(params[:organization])
    if @org.save
      @picture = Picture.new(:avatar => params[:organization][:picture_attributes][:avatar])
      @picture.organization_id = @org.id
      @picture.save

      logger.info "---------- inside Avtar controller ---------------"
      logger.info @picture.inspect
      session[:org_id] = @org.id
      redirect_to new_admin_user_path :notice => 'Organization created successfully.'
    else
      render 'new'
    end
  end
end


<div>
    <h4>FillUp organization details.</h4>
    <%= form_for @organization, :url => organizations_path do |f| %>
        <%= f.label :name, "Name" %>
        <%= f.text_field :name %>

        <%= f.label :contect_number, "Contact Number" %>
        <%= f.text_field :contect_number %>

        <%= f.label :address, "Address" %>
        <%= f.text_field :address %>

        <%= f.label :website, "Website" %>
        <%= f.text_field :email %>

        <%= f.label :company_type, "Type" %>
        <%= f.text_field :type_of_organization %>

        <%= f.fields_for :picture_attributes, :html => { :multipart => true } do |p| %>
            <%= p.label :avatar, "My Avatar" %>
            <%= p.file_field :avatar %><br/>
        <%end%>

        <%= f.submit :Create, :class => 'btn btn-primary' %>    
    <%end%> 
</div>
于 2013-10-14T11:30:44.697 回答