我希望用户能够选择他们说的语言。我已经设置了关联,表属性和表单的一部分。当我选择一种语言并提交表单时,我会转到rails控制台并执行u.languages
,但我得到一个空数组:=> []
以下是我提交表单时的日志:
Started POST "/update_user_via_user" for 127.0.0.1 at 2016-03-18 13:26:03 +0200
ActiveRecord::SchemaMigration Load (0.4ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by UsersController#update_user_via_user as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"CB1Qca0VrBcap9qO6VpKfoi2dG8GNG+tGGNDgCnFEv4E=", "user"=>{ "fullname"=>"John Doe", "languages"=>["", "1", "2"]}, "commit"=>"Save"}
User Load (28.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 3 ORDER BY "users"."id" ASC LIMIT 1
Unpermitted parameters: languages
(0.1ms) begin transaction
(0.1ms) commit transaction
Redirected to http://127.0.0.1:3000/setup_profile
Completed 302 Found in 163ms (ActiveRecord: 29.5ms)
现在,如果仔细观察一下loogs,你会看到“未经许可的参数:语言”。
在我的users_controller中,我有以下内容:
def user_params
params.require(:user).permit(:languages, :fullname)
end
和自定义操作:
def update_user_via_user
if current_user.update(user_params)
flash.notice = "Your profile was sent for moderation. We will moderate it asap!"
else
flash.alert = "Something went wrong! Please try again."
end
redirect_to root_path
end
其他一些参考文献:(最后我的问题)
schema.rb:
语言表:
create_table "languages", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
end
用户表:
t.string "languages"
language.rb model:
class Language < ActiveRecord::Base
belongs_to :user
end
和user.rb模型:
class User < ActiveRecord::Base
has_many :languages
end
观点:
<%= f.label :languages %>
<%= f.select :languages, Language.all.map{ |l| [l.name, "#{l.id}"] }, {}, { :multiple => true } %>
我不确定为什么不允许“语言”以及我的代码概念是否正确
答案 0 :(得分:3)
class Language < ActiveRecord::Base
belongs_to :user
end
这将在用户和语言之间建立一个两个很多的关系,这不是你想要的。你想要的是多对多关系:
因此,为了跟踪这一点,我们需要第三个表:
language_users
就是所谓的连接表。你可以随意命名表格 - 称之为a + _ + bs
只是一种约定。
我们还需要设置模型以使用连接表。
class User < ActiveRecord::Base
has_many :language_users
has_many :languages, through: :language_users
end
class Language < ActiveRecord::Base
has_many :language_users
has_many :users, through: :language_users
end
# this is a join model that links User & Language
class LanguageUser < ActiveRecord::Base
belongs_to :user
belongs_to :language
end
要创建表单元素,用户可以在其中选择要使用的语言:
<%= f.collection_select(:languages_ids, Language.all, :id, :name, multiple: true) %>
或者:
<%= f.collection_check_boxes(:languages_ids, Language.all, :id, :name) %>
languages_ids
是ActiveRecord为has_many
关联创建的一个特殊访问器,它允许您通过传递一组ID来设置多个关联。
答案 1 :(得分:0)
我认为Deep的答案是正确的,基于this exchange。
我启动了控制台并执行了此操作:
irb(main):001:0> x = ActionController::Parameters.new(user: {fullname: "John Doe", languages: ['','1','2']})
=> {"user"=>{"fullname"=>"John Doe", "languages"=>["", "1", "2"]}}
irb(main):002:0> y = x.require(:user).permit(:fullname, :languages => [])
=> {"fullname"=>"John Doe", "languages"=>["", "1", "2"]}
irb(main):003:0> y[:languages]
=> ["", "1", "2"]
所以,嗯。
您现在收到的错误消息是什么?和原来一样吗?