我如何纠正这个模型关联?
我创建了一个相册模型和一个照片模型,并将其添加到现有的 Rails 应用程序中。我已将照片模型设置为相册模型,并将相册模型设置为属于用户模型的现有配置文件模型。我不知道我是否将它们关联错误以及为什么会收到错误。
值得注意的是,当我转到 URL/albums 时,一切都会正常工作,但是当我转到 URL/profiles/1 时(下面的代码粘贴在views/profile/文件夹中的 show.html.erb 文件中),那么我收到以下错误。
这是一个简单的问题,我无法解决。四个模型文件如下:
Album.rb:
class Album < ActiveRecord::Base
belongs_to :profile
has_many :photos, :dependent => :destroy
accepts_nested_attributes_for :photos, :allow_destroy => true
end
Profile.rb:
class Profile < ActiveRecord::Base
belongs_to :user
has_many :albums
def self.get_location(profile)
location = []
location << profile.city unless profile.city.blank?
location << profile.state unless profile.state.blank?
location << profile.country unless profile.country.blank?
location << profile.postal_code unless profile.postal_code.blank?
location
end
def self.missing_fields(profile)
missing = []
if profile.first_name.blank?
missing << "first name"
end
if profile.last_name.blank?
missing << "last name"
end
if profile.job_title.blank?
missing << "job title"
end
missing
end
end
Photo.rb:
require 'paperclip'
class Photo < ActiveRecord::Base
belongs_to :album
has_attached_file :upload,
:url => "/images/:id/:style/:basename.:extension",
:path => ":rails_root/public/images/:id/:style/:basename.:extension",
:styles => {
:thumb => "75x75>",
:small => "200x200>"
}
#add in any validations you may want
end
User.rb:
class User < ActiveRecord::Base
include Gravtastic
gravtastic :size => 120
# associations
has_many :albums
has_many :photos, :through => :albums
has_many :authorizations, :dependent => :destroy
has_one :profile, :dependent => :destroy
has_many :resumes, :dependent => :destroy, :order => 'created_at DESC'
has_many :thoughts, :dependent => :destroy, :order => 'created_at DESC'
has_many :user_threads, :dependent => :destroy, :order => 'created_at ASC'
accepts_nested_attributes_for :profile
# virtual attributes
attr_accessor :first_name, :last_name
# validations
validates_presence_of :first_name
validates_presence_of :last_name
validates_length_of :username, :minimum => 4, :message => " is too short"
validates :email, :email => {:message => " is not valid"}
validates_uniqueness_of :email, :case_sensitive => false
validates_uniqueness_of :username, :case_sensitive => false
validates_length_of :password, :minimum => 4, :message => " is too short"
# authlogic
acts_as_authentic do |config|
config.crypto_provider = Authlogic::CryptoProviders::MD5
config.maintain_sessions = false
config.validate_email_field = false
config.validate_login_field = false
config.validate_password_field = false
config.login_field = :email
config.validate_login_field = false
end
def self.create_from_hash!(hash)
user = User.new(:username => Time.now.to_i, :email => '', :auth_provider => hash['provider'])
user.save(:validate => false)
if hash['provider'].downcase == 'twitter'
user.profile = Profile.create(:first_name => Twitter::Client.new.user(hash['user_info'] ['nickname'].to_s).name)
else
user.profile = Profile.create(:first_name => hash['user_info']['first_name'], :last_name => hash['user_info']['last_name'])
end
user
end
def deliver_password_reset_instructions!
reset_perishable_token!
UserMailer.deliver_password_reset_instructions(self)
end
def activate!
self.active = true
save(false)
end
def deliver_activation_instructions!
reset_perishable_token!
UserMailer.deliver_activation_instructions(self)
end
end
配置文件控制器有此片段:
def show
@user = User.find_by_username(params[:id])
@profile = @user.profile
@location = Profile.get_location(@profile)
@resumes = @user.resumes
@albums = @user.albums
@photos = @user.photos
@thoughts = @user.thoughts
@shouts = UserThread.find_profile_shouts(@profile)
@shouters = UserThread.find_shouters(@shouts)
@user_thread = UserThread.new
end
视图有此:
<div id="profile_right_col">
<h2>Albums</h2>
<p>
<b>Name:</b>
<%= @albums %><br />
<% @albums.photos.each do |photo| %>
<h3><%= photo.title %></h3>
<%= image_tag photos.upload.url(:small) %>
<% end %>
</p>
<%= link_to 'Edit', edit_album_path(@albums) %> |
<%= link_to 'Back', albums_path %>
</div>
操作控制器异常显示:
ActiveRecord::StatementInvalid in Profiles#show
Showing /Users/pawel/Ruby/Apps/cvf/app/views/profiles/show.html.erb where line #137 raised:
SQLite3::SQLException: no such column: albums.user_id: SELECT "albums".* FROM "albums" WHERE ("albums".user_id = 4)
Extracted source (around line #137):
<h2>Albums</h2>
<p>
<b>Name:</b>
<%= @albums %><br />
<% @albums.photos.each do |photo| %>
<h3><%= photo.title %></h3>
I've created an album model and a photo model and added it to an existing rails application. I've made the photos model belong to the album model and the album model belong to an existing profile model that belongs to a user model. I don't know if I've associated them wrong and why I'm getting an error.
It's worth noting that when I go to URL/albums then everything works as it should but when I go to URL/profiles/1 (the code below is pasted in the show.html.erb file in the views/profile/ folder) then I get the error below.
This is a simple problem that I just can't solve. The four model files are below:
Album.rb:
class Album < ActiveRecord::Base
belongs_to :profile
has_many :photos, :dependent => :destroy
accepts_nested_attributes_for :photos, :allow_destroy => true
end
Profile.rb:
class Profile < ActiveRecord::Base
belongs_to :user
has_many :albums
def self.get_location(profile)
location = []
location << profile.city unless profile.city.blank?
location << profile.state unless profile.state.blank?
location << profile.country unless profile.country.blank?
location << profile.postal_code unless profile.postal_code.blank?
location
end
def self.missing_fields(profile)
missing = []
if profile.first_name.blank?
missing << "first name"
end
if profile.last_name.blank?
missing << "last name"
end
if profile.job_title.blank?
missing << "job title"
end
missing
end
end
Photo.rb:
require 'paperclip'
class Photo < ActiveRecord::Base
belongs_to :album
has_attached_file :upload,
:url => "/images/:id/:style/:basename.:extension",
:path => ":rails_root/public/images/:id/:style/:basename.:extension",
:styles => {
:thumb => "75x75>",
:small => "200x200>"
}
#add in any validations you may want
end
User.rb:
class User < ActiveRecord::Base
include Gravtastic
gravtastic :size => 120
# associations
has_many :albums
has_many :photos, :through => :albums
has_many :authorizations, :dependent => :destroy
has_one :profile, :dependent => :destroy
has_many :resumes, :dependent => :destroy, :order => 'created_at DESC'
has_many :thoughts, :dependent => :destroy, :order => 'created_at DESC'
has_many :user_threads, :dependent => :destroy, :order => 'created_at ASC'
accepts_nested_attributes_for :profile
# virtual attributes
attr_accessor :first_name, :last_name
# validations
validates_presence_of :first_name
validates_presence_of :last_name
validates_length_of :username, :minimum => 4, :message => " is too short"
validates :email, :email => {:message => " is not valid"}
validates_uniqueness_of :email, :case_sensitive => false
validates_uniqueness_of :username, :case_sensitive => false
validates_length_of :password, :minimum => 4, :message => " is too short"
# authlogic
acts_as_authentic do |config|
config.crypto_provider = Authlogic::CryptoProviders::MD5
config.maintain_sessions = false
config.validate_email_field = false
config.validate_login_field = false
config.validate_password_field = false
config.login_field = :email
config.validate_login_field = false
end
def self.create_from_hash!(hash)
user = User.new(:username => Time.now.to_i, :email => '', :auth_provider => hash['provider'])
user.save(:validate => false)
if hash['provider'].downcase == 'twitter'
user.profile = Profile.create(:first_name => Twitter::Client.new.user(hash['user_info'] ['nickname'].to_s).name)
else
user.profile = Profile.create(:first_name => hash['user_info']['first_name'], :last_name => hash['user_info']['last_name'])
end
user
end
def deliver_password_reset_instructions!
reset_perishable_token!
UserMailer.deliver_password_reset_instructions(self)
end
def activate!
self.active = true
save(false)
end
def deliver_activation_instructions!
reset_perishable_token!
UserMailer.deliver_activation_instructions(self)
end
end
The profile controller has this snippet:
def show
@user = User.find_by_username(params[:id])
@profile = @user.profile
@location = Profile.get_location(@profile)
@resumes = @user.resumes
@albums = @user.albums
@photos = @user.photos
@thoughts = @user.thoughts
@shouts = UserThread.find_profile_shouts(@profile)
@shouters = UserThread.find_shouters(@shouts)
@user_thread = UserThread.new
end
The view has this:
<div id="profile_right_col">
<h2>Albums</h2>
<p>
<b>Name:</b>
<%= @albums %><br />
<% @albums.photos.each do |photo| %>
<h3><%= photo.title %></h3>
<%= image_tag photos.upload.url(:small) %>
<% end %>
</p>
<%= link_to 'Edit', edit_album_path(@albums) %> |
<%= link_to 'Back', albums_path %>
</div>
The Action Controller exception shows:
ActiveRecord::StatementInvalid in Profiles#show
Showing /Users/pawel/Ruby/Apps/cvf/app/views/profiles/show.html.erb where line #137 raised:
SQLite3::SQLException: no such column: albums.user_id: SELECT "albums".* FROM "albums" WHERE ("albums".user_id = 4)
Extracted source (around line #137):
<h2>Albums</h2>
<p>
<b>Name:</b>
<%= @albums %><br />
<% @albums.photos.each do |photo| %>
<h3><%= photo.title %></h3>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您没有在显示操作中定义
@album
变量(您有 @albums 以及需要遍历 @albums 数组的视图)。所以它的值为零并且没有方法照片。You dont have
@album
variable defined in your show action (you have @albums and the in the views you need to go through @albums array). So its value is nil and it doesn`t have method photos.在我将
Paperclip::Railtie.insert
添加到我的 application.rb 后,它就起作用了。It worked after I added
Paperclip::Railtie.insert
to my application.rb.