Rails的 - 如何显示关联模型的属性 [英] Rails - how to show attribute of an associated model

查看:122
本文介绍了Rails的 - 如何显示关联模型的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让Rails中4应用程序

我刚才问此相关的问题,并得到了明确的答案。看来我无法理解如何把这个逻辑和其他地方使用它。

<一个href=\"http://stackoverflow.com/questions/32898541/rails-how-to-show-attributes-from-a-parent-object/32904305#32904305\">Rails如何显示从父对象属性

我有一个用户模型,轮廓模型项目模型和大学的模式。

关联是:

 档案属于大学
档案所属的用户
大学有很多的配置文件
大学有很多项目
项目HABTM用户
项目属于大学

在我的项目的控制器,我定义@creator如下:

  DEF创建
    logger.debug的xxx创建工程
    #authorise @project
    @project = Project.new(project_params)
    @ project.creator_id = current_user.id
    @ project.users&LT;&LT;当前用户
    做的respond_to |格式|
      如果@ project.save        format.html {redirect_to的@project}
        format.json {渲染动作:'秀',状态:创建,地点:@project}
      其他
        format.html {渲染动作:'新'}
        format.json {渲染JSON:@ project.errors,状态:unprocessable_entity}
      结束
    结束
  结束

我尝试定义creator_profile是这样的:

 高清节目
    #authorise @project    @project = Project.find(PARAMS [:ID])
    @creator = User.find(@ project.creator_id)
    @creator_profile = @ creator.profile  结束

在我的UNI表,我有属性称为标志和名称。我使用的头像上传在我所定义的标识(这就是为什么我下面有两个.logo)。

在我的项目,表演,我想要显示的大学,该项目的创造者属于

我试过这样:

 &LT;%= IMAGE_TAG(@ creator_profile.university.logo.logo)%GT;
        &LT; D​​IV CLASS =generaltext&GT;&LT;%= @ creator_profile.university.name%GT; &LT; / DIV&GT;

我得到这样的结果:未定义的方法`标志'的零:NilClass

根据链接到我的问题上面。

 &LT;%= IMAGE_TAG(creator_profile.university.logo.logo)%GT;
            &LT; D​​IV CLASS =generaltext&GT;&LT;%= creator_profile.university.name%GT; &LT; / DIV&GT;

我得到这样的结果:

 未定义的局部变量或方法`creator_profile'的#&LT;#&LT;班级:0x007f998f17ad88&GT;:&0x007f998d1ce318 GT;

我不知道我理解的答案给我的previous问题非常详细的解释。如果第一个版本是正确的,那么我不明白,在所有的解释。如果第二个版本是正确的,那么为什么此错误消息来呢?

我想知道如果发生问题离开这里不是大学和用户之间的关联?我希望,根据谁创建的项目,发现里面的创造者属于UNI用户。

这就是为什么我尝试:

 &LT;%= IMAGE_TAG(creator_profile.project.university.logo.logo)%GT;
                &LT; D​​IV CLASS =generaltext&GT;&LT;%= creator_profile.project.university.name%GT; &LT; / DIV&GT;

我得到这个错误:

 未定义的方法'项目'的#&LT;简介:0x007f998ada41b8&GT;


解决方案

  

看来我无法理解如何把这个逻辑和其他地方使用它。


我不认为你的AP preciate ActiveRecord关联在Rails中是如何工作的。我会进一步解释下跌的一页。


您的关联将是问题的可能原因。

设置复杂的关联总是棘手 - 这是最好把数据作为单独地

下面就是我想制定模型/协会:

 #应用程序/模型/ university_student.rb
一流的大学学生和LT; ActiveRecord的::基地
   belongs_to的:大学
   belongs_to的:学生,CLASS_NAME:用户# - &GT;学生卡
结束#应用程序/模型/ user.rb
类User&LT; ActiveRecord的::基地
   的has_many:展示位置,CLASS_NAME:大学学生,foreign_key:student_id数据# - &GT; user.placements
   的has_many:高校,通过:展示位置# - &GT; user.universities   has_and_belongs_to_many:项目# - &GT; user.projects   HAS_ONE:轮廓# - &GT; user.profile(头像等)   的has_many:created_projects,CLASS_NAME:项目,foreign_key:creator_id
结束#应用程序/模型/ profile.rb
类档案&LT; ActiveRecord的::基地
   belongs_to的:用户# - &GT;存储化身在这里。这可以在整个应用程序中使用
结束#应用程序/模型/ university.rb
一流大学&LT; ActiveRecord的::基地
   的has_many:项目
   的has_many:学生,CLASS_NAME:大学学生# - &GT; university.students
结束#应用程序/模型/ project.rb
类项目和LT; ActiveRecord的::基地
   belongs_to的:大学
   belongs_to的:创造者,CLASS_NAME:用户# - &GT; creator_id   has_and_belongs_to_many:用户   代表:配置文件,来:创造者,preFIX:真# - &GT; @ project.creator_profile
结束

这可以让你做到以下几点:

  DEF创建
   @project = curent_user.created_projects.new project_params
   @ project.users&LT;&LT;当前用户

由于该协会实际上联想的数据,您就可以做到以下几点:

 高清节目
    @project = Project.find PARAMS [:ID]
    #@ creator_profile = @ p​​roject.creator.profile
    @creator_profile = @#project.creator_profile - &GT;如果您使用的机型所列的委托方法
结束

-


  

在我的项目,表演,我想显示大学项目创建者属于


 #应用程序/控制器/ projects_controller.rb
类ProjectsController&LT; ApplicationController中
   高清节目
      #@项目= Project.find PARAMS [:ID]
      @project = current_user.created_projects.find PARAMS [:ID]
   结束
结束#应用程序/视图/项目/ show.html.erb
&所述;%= @ p​​roject.creator.universities.first%GT;

以上我的code允许多个大学。关于它的思考,应该限于一个,但我会离开它是现在,也许以后改变它。


  

在我的UNI表,我有属性称为标志和名称。我使用的头像上传在我所定义的标识(这就是为什么我有空两.logo)。


不要使用两个标志方法,它是一个反模式(下文解释)


对此的解决办法是双重的:

首先,确保你调用 @ creator_profile.university 通过以下内容:

 &LT;&GT%= @ creator_profile.university%;

如果这个工程,就意味着你有 .logo.logo (下文详述),如果没有,这意味着你已经没有定义问题 @creator_profile 或正确的大学关联。

其次,你需要确保你有正确的控制器/视图设置。

对许多人的问题 - 尤其是新手 - 是他们根本不明白Rails的与控制器和放大器的工作方式;意见。您需要AP preciate,每次渲染视图时,的只有的数据它可以访问的是,你在相应的定义控制器行动...

 #应用程序/控制器/ projects_controller.rb
类ProjectsController&LT; ApplicationController中
    高清节目
        @project = Project.find PARAMS [:ID]
        @creator_profile = @ p​​roject.creator_profile
    结束
结束#应用程序/视图/项目/ show.html.erb
&LT;%= content_tag:DIV,@ creator_profile.universities.first.name,等级:generaltext%GT;


花絮


  1. @ project.creator_id = current_user.id

这不应该被定义。

您应该能够改变 foreign_key 在联想,让Rails会自动地定义 creator_id 为您提供:

 #应用程序/模型/ project.rb
类项目和LT; ActiveRecord的::基地
    belongs_to的:创造者,等级:用户# - &GT; foreign_key应该是:creator_id
结束#应用程序/控制器/ projects_controller.rb
类ProjectsController&LT; ApplicationController中
   打造高清
      @project = current_user.created_projects.new project_params# - &GT;自动填充外键。

-

<醇开始=2>
  • .logo.logo

  • 这是一个反模式

    调用同样的方法两次简直是坏习惯的? - 你为什么这样做。

    您既想委派任何递归数据你试图访问(如用 .creator_profile 上面的例子),或者你要重组的功能。

    您希望以下内容:

    如果您有委托给资产的模式,你可以逃脱如下:

     &LT;&GT%= @ creator_profile.university.images.logo%;

    I am trying to make an app in Rails 4.

    I just asked this related question and got a clear answer. It seems I can't understand how to take that logic and apply it elsewhere.

    Rails How to show attributes from a parent object

    I have a user model, profile model a projects model and a universities model.

    Associations are:

    Profile belongs to university
    Profile belongs to user
    University has many profiles
    University has many projects
    Projects HABTM user
    Projects belong to universities
    

    In my projects controller, I define @creator as 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 do |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 to define creator_profile like this:

    def show
        #authorise @project
    
        @project = Project.find(params[:id])
        @creator = User.find(@project.creator_id)
        @creator_profile = @creator.profile
    
      end
    

    In my uni table, I have attributes called logo and name. I use avatar uploader in which i have logo defined (that's why I have two .logo below).

    In my projects, show, I want to display the university that the project creator belongs to.

    I've tried this:

    <%= image_tag(@creator_profile.university.logo.logo) %> 
            <div class="generaltext"><%= @creator_profile.university.name %> </div>
    

    I get this result: undefined method `logo' for nil:NilClass

    Based on the link to my problem above

    <%= image_tag(creator_profile.university.logo.logo) %> 
                <div class="generaltext"><%= creator_profile.university.name %> </div>
    

    I get this result:

    undefined local variable or method `creator_profile' for #<#<Class:0x007f998f17ad88>:0x007f998d1ce318>
    

    I'm not sure I understood the very detailed explanations given in the answer to my previous question. If the first version is right, then I don't understand the explanation at all. If the second version is right, then why does this error message come up?

    Im wondering if the problem arises out of there not being an association between university and user? I was hoping, based on the user who created the project, to find the uni that the creator belongs to.

    That's why i tried:

    <%= image_tag(creator_profile.project.university.logo.logo) %> 
                    <div class="generaltext"><%= creator_profile.project.university.name %> </div>
    

    I get this error:

    undefined method `project' for #<Profile:0x007f998ada41b8>
    

    解决方案

    It seems I can't understand how to take that logic and apply it elsewhere.

    I don't think you appreciate how ActiveRecord associations work in Rails. I'll explain further down the page.


    Your associations will be the likely cause of the problem.

    Setting up complicated associations is always tricky - it's best to keep the data as separate as possible.

    Here's how I'd construct the 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. This can be 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 you to do the following:

    def create
       @project = curent_user.created_projects.new project_params
       @project.users << current_user
    

    Because the associations actually associate your data, you'll be able to do the following:

    def show
        @project = Project.find params[:id]
        #@creator_profile = @project.creator.profile
        @creator_profile = @project.creator_profile #-> if you use the delegate method outlined in the models
    end
    

    --

    In my projects, show, I want to display the university that the 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 for multiple universities. Thinking about it, it should be limited to one, but I'll leave it as is for now, maybe change it later.

    In my uni table, I have attributes called logo and name. I use avatar uploader in which i have logo defined (that's why I have two .logo below).

    Don't use two logo method, it's an antipattern (explained below)


    The fix for this is two-fold:

    Firstly, make sure you're calling @creator_profile.university with the following:

    <%= @creator_profile.university %> 
    

    If this works, it means you have a problem with .logo.logo (detailed below), if it doesn't, it means you've not defined @creator_profile or the university association correctly.

    Secondly, you need to ensure you have the correct controller/view setup.

    The problem for many people - especially beginners - is they simply don't understand the way Rails works with controllers & views. You need to appreciate that each time you render a view, the only data it has access to is that which you define in the 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

    1. @project.creator_id = current_user.id

    This should not have to be defined.

    You should be able to change the foreign_key in the association, so that Rails will automagically define the creator_id for you:

    #app/models/project.rb
    class Project < ActiveRecord::Base
        belongs_to :creator, class: "User" #-> foreign_key should be :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.
    

    --

    1. .logo.logo

    This is an antipattern.

    Calling the same method twice is simply bad practice - why are you doing it?

    You either want to delegate any recursive data you're trying to access (such as the example with .creator_profile above), or you'll want to restructure that functionality.

    You want the following:

    If you have to delegate to an assets model, you could get away with the following:

    <%= @creator_profile.university.images.logo %>
    

    这篇关于Rails的 - 如何显示关联模型的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆