orm - Rails has_many :through association: retrieve foreign attribute through foreign key -
in our rails app, there 3 models:
class user < activerecord::base has_many :administrations, dependent: :destroy has_many :calendars, through: :administrations end class administration < activerecord::base belongs_to :user belongs_to :calendar end class calendar < activerecord::base has_many :administrations, dependent: :destroy has_many :users, through: :administrations end
and here corresponding migrations:
class createusers < activerecord::migration def change create_table :users |t| t.string :first_name t.string :last_name t.string :email t.timestamps null: false end end end class createadministrations < activerecord::migration def change create_table :administrations |t| t.references :user, index: true, foreign_key: true t.references :calendar, index: true, foreign_key: true t.string :role t.timestamps null: false end end end class createcalendars < activerecord::migration def change create_table :calendars |t| t.string :name t.timestamps null: false end end end
edit: here our userscontroller
:
class userscontroller < applicationcontroller before_action :logged_in_user, only: [:edit, :update, :destroy] before_action :correct_user, only: [:edit, :update] before_action :admin_user, only: [:index, :destroy] def index @users = user.paginate(page: params[:page], :per_page => 10) end def show @user = user.find(params[:id]) @administrations = @user.administrations @calendar = current_user.calendars.build if logged_in? end def new @user = user.new end def create @user = user.new(user_params) if @user.save @user.send_activation_email flash[:info] = "please check email activate account." redirect_to root_url else render 'new' end end def edit @user = user.find(params[:id]) end def update @user = user.find(params[:id]) if @user.update_attributes(user_params) flash[:success] = "profile updated" redirect_to @user else render 'edit' end end def destroy user.find(params[:id]).destroy flash[:success] = "user deleted" redirect_to users_url end private def user_params params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation) end # before filters # confirms correct user. def correct_user @user = user.find(params[:id]) redirect_to(root_url) unless current_user?(@user) end # confirms admin user. def admin_user redirect_to(root_url) unless current_user.try(:admin?) end end
once user logged in (authentication system , running), want display on profile (users#show), calendars has created.
we have seeded database following instances:
user.create!(first_name: "andy") # user's id 1. calendar.create!(name: "calendara") calendar.create!(name: "calendarb") calendar.create!(name: "calendarc") administration.create!(user_id: 1, calendar_id: 1, role: "creator") administration.create!(user_id: 1, calendar_id: 2, role: "editor") administration.create!(user_id: 1, calendar_id: 3, role: "viewer")
then, have created _administration.html.erb
partial:
<li id="administration-<%= administration.id %>"> <span class="name"><%= administration.calendar_id %></span> </li>
and included in our user show.html.erb
file:
<p><%= @user.first_name %>'s calendars</p> <% if @user.administrations.any? %> <%= render @administrations %> <% end %>
and working, get:
andy's calendars:
- 1
- 2
- 3
however, each user, not id
s of calendars, name
s too, this:
andy's calendars:
- 1 calendara
- 2 calendarb
- 3 calendarc
so tried update _administration.html.erb
partial follows:
<li id="administration-<%= administration.id %>"> <span class="name"><%= administration.calendar_id.name %></span> </li>
which results in following error:
nomethoderror in userscontroller#show undefined method `name' 1:fixnum application trace | framework trace | full trace app/views/administrations/_administration.html.erb:2:in `_app_views_administrations__administration_html_erb__2225316747000531998_70329866860100' app/views/users/show.html.erb:32:in `_app_views_users_show_html_erb___891585127045041471_70329832995240'
how can access "foreign" attribute name
calendar
model through foreign key calendar_id
in join administration
model?
administration.calendar.name
should work if associations set correctly.
alternatively, add method administration
:
def calendar_name calendar.name end
and call administration.calendar_name
Comments
Post a Comment