我正在使用Ruby on Rails构建一个家庭相册应用程序。我有两个主要表:“家庭”和“成员”。家庭有很多成员。
当我创建一个“家庭”的新“成员”时,我试图跟踪新成员与原始成员的关系。我的应用程序允许您创建一个原始成员,然后必须从现有成员的显示页面创建所有其他成员。我们的想法是,在没有与现有成员建立关系的情况下,不允许将任何新成员添加到家庭中。这将避免与其他任何人无关的浮动成员。
我有一个名为“parent_id”的列。创建新成员时,可以将当前成员的id(表单在成员显示视图中)添加为新成员的parent_id。这会链接记录,以便以后引用它们。
我的问题很简单。在成员的节目视图中,我想要一个表来显示所有拥有parent_id ==当前成员id的成员。很简单,但我不能让它工作。这就是我现在所拥有的:
<table class="table table-striped">
<tr>
<td>First</td>
<td>Last</td>
<td>Birthplace</td>
</tr>
<% @members.where("parent_id == @member.id").each do |p| %>
<tr>
<td><%= p.first_name %></td>
<td><%= p.last_name %></td>
<td><%= p.birthplace %></td>
</tr>
<% end %>
</table>
这是此代码抛出的错误:
SQLite3::SQLException: near ".": syntax error: SELECT "members".* FROM "members" WHERE "members"."family_id" = ? AND (parent_id == @member.id)
以下是我的成员控制器中的show动作:
def show
@family = Family.find(params[:family_id])
@member = Member.find(params[:id])
@new = Member.new
@members = @family.members
end
这是我的两个表的架构:
create_table "families", force: :cascade do |t|
t.string "title"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "members", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.string "birthplace"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "family_id"
t.integer "parent_id"
t.integer "child_id"
t.integer "sibling_id"
end
答案 0 :(得分:1)
您尝试访问id
对象中的@members
属性,该属性可能是ActiveRecord_Associations_CollectionProxy
模型中的Member
。
如果你创建一个@members.inspect
,你会看到它内部的每个元素,因为数组值有id
但不是对象本身。
如果您遍历每个元素,则可以获得每个member
id属性,然后通过这种方式,您可以进行比较parent_id = member.id
,如果执行'parent_id = ?', member.id
,这可能更安全避免SQLi。
但我认为您可以更轻松地检查@members
上的成员,只需比较其属性:
<% @members.each do |member| %>
<% if member.parent_id == member.id %>
<tr>
<td><%= member.first_name %></td>
<td><%= member.last_name %></td>
<td><%= member.birthplace %></td>
</tr>
<% end %>
<% end %>