associations - Rails - how to show attribute of an associated model -
i trying make app in rails 4.
i asked related question , got clear answer. seems can't understand how take logic , apply elsewhere.
rails how show attributes parent object
i have user model, profile model projects model , universities model.
associations are:
profile belongs university profile belongs user university has many profiles university has many projects projects habtm user projects belong universities
in projects controller, define @creator follows:
def create logger.debug "xxx create project" #authorise @project @project = project.new(project_params) @project.creator_id = current_user.id @project.users << current_user respond_to |format| if @project.save format.html { redirect_to @project } format.json { render action: 'show', status: :created, location: @project } else format.html { render action: 'new' } format.json { render json: @project.errors, status: :unprocessable_entity } end end end
i try define creator_profile this:
def show #authorise @project @project = project.find(params[:id]) @creator = user.find(@project.creator_id) @creator_profile = @creator.profile end
in uni table, have attributes called logo , name. use avatar uploader in have logo defined (that's why have 2 .logo below).
in projects, show, want display university project creator belongs to.
i've tried this:
<%= image_tag(@creator_profile.university.logo.logo) %> <div class="generaltext"><%= @creator_profile.university.name %> </div>
i result: undefined method `logo' nil:nilclass
based on link problem above
<%= image_tag(creator_profile.university.logo.logo) %> <div class="generaltext"><%= creator_profile.university.name %> </div>
i result:
undefined local variable or method `creator_profile' #<#<class:0x007f998f17ad88>:0x007f998d1ce318>
i'm not sure understood detailed explanations given in answer previous question. if first version right, don't understand explanation @ all. if second version right, why error message come up?
im wondering if problem arises out of there not being association between university , user? hoping, based on user created project, find uni creator belongs to.
that's why tried:
<%= image_tag(creator_profile.project.university.logo.logo) %> <div class="generaltext"><%= creator_profile.project.university.name %> </div>
i error:
undefined method `project' #<profile:0x007f998ada41b8>
it seems can't understand how take logic , apply elsewhere.
i don't think appreciate how activerecord associations work in rails. i'll explain further down page.
your associations cause of problem.
setting complicated associations tricky - it's best keep data separate possible.
here's how i'd construct models / associations:
#app/models/university_student.rb class universitystudent < activerecord::base belongs_to :university belongs_to :student, class_name: "user" #-> student_id end #app/models/user.rb class user < activerecord::base has_many :placements, class_name: "universitystudent", foreign_key: :student_id #-> user.placements has_many :universities, through: :placements #-> user.universities has_and_belongs_to_many :projects #-> user.projects has_one :profile #-> user.profile (avatar etc) has_many :created_projects, class_name: "project", foreign_key: :creator_id end #app/models/profile.rb class profile < activerecord::base belongs_to :user #-> store avatar here. can used across entire app end #app/models/university.rb class university < activerecord::base has_many :projects has_many :students, class_name: "universitystudent" #-> university.students end #app/models/project.rb class project < activerecord::base belongs_to :university belongs_to :creator, class_name: "user" #-> creator_id has_and_belongs_to_many :users delegate :profile, to: :creator, prefix: true #-> @project.creator_profile end
this allows following:
def create @project = curent_user.created_projects.new project_params @project.users << current_user
because associations associate data, you'll able following:
def show @project = project.find params[:id] #@creator_profile = @project.creator.profile @creator_profile = @project.creator_profile #-> if use delegate method outlined in models end
--
in projects, show, want display
university
project creator
belongs to.
#app/controllers/projects_controller.rb class projectscontroller < applicationcontroller def show #@project = project.find params[:id] @project = current_user.created_projects.find params[:id] end end #app/views/projects/show.html.erb <%= @project.creator.universities.first %>
my code above allows multiple universities. thinking it, should limited one, i'll leave now, maybe change later.
in uni table, have attributes called logo , name. use avatar uploader in have logo defined (that's why have 2 .logo below).
don't use 2 logo
method, it's antipattern (explained below)
the fix two-fold:
firstly, make sure you're calling @creator_profile.university
following:
<%= @creator_profile.university %>
if works, means have problem .logo.logo
(detailed below), if doesn't, means you've not defined @creator_profile
or university
association correctly.
secondly, need ensure have correct controller/view setup.
the problem many people - beginners - don't understand way rails works controllers & views. need appreciate each time render view, only data has access define in corresponding controller
action...
#app/controllers/projects_controller.rb class projectscontroller < applicationcontroller def show @project = project.find params[:id] @creator_profile = @project.creator_profile end end #app/views/projects/show.html.erb <%= content_tag :div, @creator_profile.universities.first.name, class: "generaltext" %>
trivia
@project.creator_id = current_user.id
this should not have defined.
you should able change foreign_key
in association, rails automagically define creator_id
you:
#app/models/project.rb class project < activerecord::base belongs_to :creator, class: "user" #-> foreign_key should :creator_id end #app/controllers/projects_controller.rb class projectscontroller < applicationcontroller def create @project = current_user.created_projects.new project_params #-> populates foreign key automatically.
--
.logo.logo
this antipattern.
calling same method twice bad practice - why doing it?
you either want delegate recursive data you're trying access (such example .creator_profile
above), or you'll want restructure functionality.
you want following:
if have delegate assets model, away following:
<%= @creator_profile.university.images.logo %>
Comments
Post a Comment