更新:感谢大家帮忙解决这个问题。我决定放弃尝试学习并为配置文件模型添加另一个图像属性。这将是现在必须做的。
我试图在rails 4中创建一个应用程序。
我有一个用户模型,上面有一个头像属性。
我也有个人资料模型。
用户:有一个个人资料 个人资料:属于User
我拆分它们的原因是因为配置文件包含所有变量,而用户包含所有未经管理员权限无法更改的固定属性。
例外是我的用户模型有一个avatar(image)属性,我希望允许用户更改。
我的代码的其他部分有用户载波,它可以工作。但是,这个用例出了点问题。
我有一个头像上传者:
class AvatarUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
# storage :file
storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def cache_dir
"#{Rails.root}/tmp/uploads"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process :resize_to_fit => [50, 50]
# end
process :resize_to_fit => [800, 800]
# Create different versions of your uploaded files:
version :thumb do
process :resize_to_fill => [200,200]
end
version :profile do
process :resize_to_fill => [345,245]
end
version :wide do
process :resize_to_fill => [951,245]
end
version :preview do
process :resize_to_fill => [90,90]
end
version :small do
process :resize_to_fill => [35,35]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg gif png)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
在我的用户模型中,我有:
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
end
在我的用户控制器中 - 我将强化参数中的头像列入白名单。
在我的个人资料控制器中,我尝试添加:
params.require(:profile).permit(:title, :overview, user_attributes: [:avatar])
我还尝试在我的个人资料模型中允许用户属性(如下所示):
belongs_to :user
accepts_nested_attributes_for :user
我在views users文件夹中有一个部分表单。
<%= simple_fields_for :user, html: { multipart: true } do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :avatar, as: :file, :label => "Add a profile image (head shot)" %>
</div>
<% end %>
该部分内容包含在我的个人资料表单中。
然后我想在我的个人资料展示视图中显示用户头像:
<div class="col-md-5 col-lg-4 vc-photo" style= "background-image: url(<%= image_url @profile.user.avatar.url if @profile.user.avatar? %>);"> </div>
但是,它只是呈现空白。
我试过了:
);“&GT;但它仍然只是呈现空白。
谁能看到我做错了什么?
当我尝试通过检查user.avatar来测试rails控制台时,我得到了这个:
u.avatar =&GT; #,last_sign_in_ip:#,confirmation_token:“73abb47df224dbc3a612b46ced66e1aba ...”,confirmed_at:“2016-04-02 07:13:57”,confirmation_sent_at:“2016-04-02 22:59:44”,unconfirmed_email:“testiest @ gmail.com“,failed_attempts:0,unlock_token:nil,locked_at:nil,created_at:”2016-04-02 07:13:57“,updated_at:”2016-04-02 22:59:43“,avatar:nil ,approved:false&gt ;, @ mounted_as =:avatar&gt;
采取以下建议
我更改了表单,以便配置文件表单现在具有:
<%= render 'users/profileimgform', f: f %>
users / profileimgform现在有:
<%= simple_fields_for :user, html: { multipart: true } do |ff| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= ff.input :avatar, as: :file, :label => "Add a profile image (head shot)" %>
</div>
<% end %>
我不确定是否需要将“ff”合并到我的个人资料表单中。我尝试用'ff'替换最后一个'f'但是错误地询问我是否应该是单个'f'。
当我尝试这个时,控制台仍然显示user.avatar是'nil'。
答案 0 :(得分:1)
我猜这段代码有错误:
public class MainViewModel : ViewModelBase
{
//constructor
public MainViewModel(BootstrapperApplication bootstrapper)
{
this.IsThinking = false;
this.Bootstrapper = bootstrapper;
this.Bootstrapper.ApplyComplete += this.OnApplyComplete;
this.Bootstrapper.DetectPackageComplete += this.OnDetectPackageComplete;
this.Bootstrapper.PlanComplete += this.OnPlanComplete;
this.Bootstrapper.CacheAcquireProgress += (sender, args) =>
{
this.cacheProgress = args.OverallPercentage;
this.Progress = (this.cacheProgress + this.executeProgress) / 2;
};
this.Bootstrapper.ExecuteProgress += (sender, args) =>
{
this.executeProgress = args.OverallPercentage;
this.Progress = (this.cacheProgress + this.executeProgress) / 2;
};
}
#region Properties
private bool installEnabled;
public bool InstallEnabled
{
get { return installEnabled; }
set
{
installEnabled = value;
RaisePropertyChanged("InstallEnabled");
}
}
private bool uninstallEnabled;
public bool UninstallEnabled
{
get { return uninstallEnabled; }
set
{
uninstallEnabled = value;
RaisePropertyChanged("UninstallEnabled");
}
}
private bool isThinking;
public bool IsThinking
{
get { return isThinking; }
set
{
isThinking = value;
RaisePropertyChanged("IsThinking");
}
}
private int progress;
public int Progress
{
get { return progress; }
set
{
this.progress = value;
RaisePropertyChanged("Progress");
}
}
private int cacheProgress;
private int executeProgress;
public BootstrapperApplication Bootstrapper { get; private set; }
#endregion //Properties
#region Methods
private void InstallExecute()
{
IsThinking = true;
Bootstrapper.Engine.Plan(LaunchAction.Install);
}
private void UninstallExecute()
{
IsThinking = true;
Bootstrapper.Engine.Plan(LaunchAction.Uninstall);
}
private void ExitExecute()
{
CustomBA.BootstrapperDispatcher.InvokeShutdown();
}
/// <summary>
/// Method that gets invoked when the Bootstrapper ApplyComplete event is fired.
/// This is called after a bundle installation has completed. Make sure we updated the view.
/// </summary>
private void OnApplyComplete(object sender, ApplyCompleteEventArgs e)
{
IsThinking = false;
InstallEnabled = false;
UninstallEnabled = false;
this.Progress = 100;
}
/// <summary>
/// Method that gets invoked when the Bootstrapper DetectPackageComplete event is fired.
/// Checks the PackageId and sets the installation scenario. The PackageId is the ID
/// specified in one of the package elements (msipackage, exepackage, msppackage,
/// msupackage) in the WiX bundle.
/// </summary>
private void OnDetectPackageComplete(object sender, DetectPackageCompleteEventArgs e)
{
if (e.PackageId == "KubeInstallationPackageId")
{
if (e.State == PackageState.Absent)
InstallEnabled = true;
else if (e.State == PackageState.Present)
UninstallEnabled = true;
}
}
/// <summary>
/// Method that gets invoked when the Bootstrapper PlanComplete event is fired.
/// If the planning was successful, it instructs the Bootstrapper Engine to
/// install the packages.
/// </summary>
private void OnPlanComplete(object sender, PlanCompleteEventArgs e)
{
if (e.Status >= 0)
Bootstrapper.Engine.Apply(System.IntPtr.Zero);
}
#endregion //Methods
#region RelayCommands
private RelayCommand installCommand;
public RelayCommand InstallCommand
{
get
{
if (installCommand == null)
installCommand = new RelayCommand(() => InstallExecute(), () => InstallEnabled == true);
return installCommand;
}
}
private RelayCommand uninstallCommand;
public RelayCommand UninstallCommand
{
get
{
if (uninstallCommand == null)
uninstallCommand = new RelayCommand(() => UninstallExecute(), () => UninstallEnabled == true);
return uninstallCommand;
}
}
private RelayCommand exitCommand;
public RelayCommand ExitCommand
{
get
{
if (exitCommand == null)
exitCommand = new RelayCommand(() => ExitExecute());
return exitCommand;
}
}
#endregion //RelayCommands
}
查看生成的html。我认为应该是这样的:
<%= simple_fields_for :user, html: { multipart: true } do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :avatar, as: :file, :label => "Add a profile image (head shot)" %>
</div>
<% end %>
答案 1 :(得分:0)
请注意,嵌套表单或复杂表单应该将模型和关联与form_for
和fields_for
帮助器连接起来,如下所示:
<%= form_for @person do |f| %>
Addresses:
<ul>
<%= f.fields_for :addresses do |addresses_form| %>
<li>
<%= addresses_form.label :kind %>
<%= addresses_form.text_field :kind %>
</li>
<% end %>
</ul>
<% end %>
模型和关联之间的连接方式是
form_for @person
构建人员表单实例f
f
构建关联表单f.fields_for :addresses
实例addresses_form
addresses_form.input ...
最后,我猜simple_fields_for
为simple_form的extra helpers,也许只适用于form_for
帮助。
以下是给定模型和控制器的示例:
应用程序/模型/ user.rb
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
has_one :profile
end
应用程序/模型/ profile.rb
class Profile < ActiveRecord::Base
belongs_to :user
accepts_nested_attributes_for :user
end
实际上,有两种方法可以修改模型的嵌套属性。
您应该使用模型和关联构建复杂的表单
更多信息:http://guides.rubyonrails.org/form_helpers.html#building-complex-forms
应用程序/控制器/ profile_controller.rb
class ProfileController < ApplicationController
private
def profile_params
params.require(:profile).permit(:title, user_attributes: [:avatar])
end
end
应用程序/视图/简档/ edit.html.erb
<%= form_for :profile do |f| %>
Avatar:
<ul>
<%= f.fields_for :user do |uf| %>
<li>
<%= uf.label :avatar %>
<%= uf.file_field :avatar %>
</li>
<% end %>
</ul>
<% end %>
你可以为这个关联属性构建一个普通的表单,但是当你必须初始化它时它很棘手和模糊,所以我不想在这里提供示例代码而不是让你感到困惑。
答案 2 :(得分:0)
我通过将头像从用户移动到个人资料来解决问题。
答案 3 :(得分:0)
我有同样的错误。如果你在Mac上,请尝试再次安装imagemagik。我用的是自制软件。您只需要运行此命令:
brew install imagemagick