如何检查变量是否已定义?

时间:2017-03-29 20:47:15

标签: ruby-on-rails ruby

我建立电子商店,会有不同的产品类别,因此每个类别的产品可以有不同的列。例如,一种产品有颜色,其他类别的其他产品没有颜色。 我想在添加新产品时,我想要在显示页面中使用我想要的颜色列,下面的这一行将不会显示(<p> <strong>Color:</strong> <%= @product.color %> </p> )。

  <p>
    <strong>Name:</strong>
    <%= @product.name %>
  </p>
  <br>
  <p>
    <strong>Description:</strong>
    <%= @product.description %>
  </p>
  <br>
  <p>
    <strong>Year of manufacture:</strong>
    <%= @product.year_of_manufacture %>
  </p>
  <br>
  <p>
   <strong>Color:</strong>
   <%= @product.color %>
 </p>

产品show.html.erb

  <div class="form-group">
    <%= f.label :name %><br>
    <%= f.text_field :name, class: "form-control" %>
  </div>
  <br>
  <div class="form-group">
    <%= f.label :description %>
    <%= f.text_area :description, class: "form-control" %>
  </div>
  <br>
  <div class="form-group">
  <%= f.label :year_of_manufacture %>
  <%= f.text_field :year_of_manufacture, class: "form-control" %>
  </div>
  <br>
  <div class="form-group">
  <%= f.label :color %>
  <%= f.text_field :color, class: "form-control" %>
  </div>

产品form.html.erb

03-29 22:36:03.546 13455-13455/com.training.criminalintent E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.training.criminalintent, PID: 13455
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.training.criminalintent/com.training.criminalintent.CrimeListActivity}: java.lang.ClassNotFoundException: Didn't find class "com.training.criminalintent.CrimeListActivity" on path: DexPathList[[zip file "/data/app/com.training.criminalintent-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2290)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
    at android.app.ActivityThread.access$800(ActivityThread.java:156)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:211)
    at android.app.ActivityThread.main(ActivityThread.java:5371)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:945)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:740)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.training.criminalintent.CrimeListActivity" on path: DexPathList[[zip file "/data/app/com.training.criminalintent-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
    at android.app.Instrumentation.newActivity(Instrumentation.java:1066)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2280)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442) 
    at android.app.ActivityThread.access$800(ActivityThread.java:156) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:211) 
    at android.app.ActivityThread.main(ActivityThread.java:5371) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:945) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:740) 
Suppressed: java.lang.ClassNotFoundException: com.training.criminalintent.CrimeListActivity
    at java.lang.Class.classForName(Native Method)
    at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
    at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
        ... 13 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available

感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

仅当产品记录的color属性定义为非空白,非nil值时才显示该部分:

<% if @product.color? %>
  <p>
    <strong>Color:</strong>
    <%= @product.color %>
  </p>
<% end %>

这相当于@product.color.present?。 ActiveRecord会自动将数据库字段映射到属性,因此如果您为该模型设置了color列,则存在。

答案 1 :(得分:3)

在ruby中,您可以使用respond_to?查看是否可以在特定对象上调用方法。真的没有&#34;未定义的变量&#34;因为@foo@blah之类的变量默认为nil,而.之后的任何内容在技术上都是ruby中的方法(例如@product.color

无论如何,试试这段代码:

<% if @product.respond_to?(:color) && @product.color.present? %>
  <p>
    <strong>Color:</strong>
    <%= @product.color %>
  </p>
<% end %>