Параметр отсутствует или значение пустое
У меня есть две модели: Boards
а также Topics
, Я хочу иметь возможность добавить Topics
в Boards
, Мои вложенные ресурсы:
resources :boards do
resources :topics
end
Моя акция "Board # Show":
def show
@board = Board.find(params[:id])
@new_topics = Topic.all
end
который перечисляет все сообщения и имеет link_to
:
<ul>
<%@new_topics.each do |i|%>
<li><%=i.title%> <%=link_to "Add", board_topic_path(@board,i), :method=> :put%></li>
<%end%>
</ul>
Я также использую strong_params для моего Boards
а также Topics
Контроллер следующим образом:
boards_controller:
def update
@board = Board.find(params[:board_id])
@topic = Topic.find(params[:id])
if @board.update(board_params)
flash[:notice] = "Added!"
@board.topics << @topic
redirect_to boards_path
else
flash[:alert] = "Problem!"
redirect_to boards_path
end
end
...
private
def board_params
params.require(:board).permit(:name,:description)
end
topics_controller:
...
private
def topic_params
params.require(:topic).permit(:title,:body,:user_id)
end
сообщение об ошибке: param отсутствует или значение пусто: topic.
2 ответа
Я считаю, что ваш дизайн не так.
С самого начала я бы сказал, что у вас есть бизнес-модель. Board
который ссылается на один или несколько Topics
и Topic
на который ссылается один или несколько Boards
, Итак, по логике у вас есть что-то вроде этого:
Итак, это два независимых ресурса, которые имеют отношение многих ко многим.
Моя модель с Rails была бы:
# routes
resources :boards
resources :topics
Другими словами, темы не являются вложенным ресурсом досок. Если бы это было так, это означало бы, что темы доски умрут, когда умрет доска. Который не ваш случай здесь, насколько я понимаю.
Теперь, поскольку отношения "многие ко многим", вам понадобится третья таблица для хранения ваших связей (таблица boards
и стол topics
не достаточно). Прочтите это в Руководствах по Rails.
Кратко:
class Board
has_and_belongs_to_many :topics
end
class Topic
has_and_belongs_to_many :boards
end
Теперь, если вы хотите добавить темы к доскам в вашем интерфейсе, вам нужна форма для редактирования доски. Эта форма, помимо других, должна иметь поле множественного выбора с темами, которые будут добавлены на доску. Тогда на вашем boards_controller#update
метод param[:board]
будет иметь атрибут topic_ids[]
который будет автоматически использоваться для привязки определенных / выбранных тем к доске, которую вы редактируете. Rails делает это автоматически.
Обратите внимание, я не склонен использовать has_and_belongs_to_many
Рельсовая ассоциация. У него много ограничений. Вы всегда можете создать свою собственную таблицу, которая будет содержать ассоциацию "многие ко многим" и другие дополнительные атрибуты, которые потребуются вашей бизнес-модели. Например, для каждой темы, прикрепленной к доске, вы можете указать тему или автора. Я не знаю. В этом случае может потребоваться более нестандартная модель:
class Board
has_many :board_topics
has_many :topics, through: :board_topics
end
class Topic
has_many :board_topics
has_many :boards, through: :board_topics
end
class BoardTopic
belongs_to :topic, inverse_of: :board_topics
belongs_to :board, inverse_of: :board_topics
.... add other attributes that give real business value to this association ....
end
В ситуации RESTful, как ваша, с этой ссылкой вы должны нажать update
действие TopicsController
с двумя params
: board_id
а также id
,
Попробуйте это вместо этого:
# boards_controller.rb
def update
@board = Board.find(params[:id])
@topic = Topic.find(params[:topic_id])
if @board.update(board_params)
flash[:notice] = "Added!"
@board.topics << @topic
redirect_to boards_path
else
flash[:alert] = "Problem!"
redirect_to boards_path
end
end
# In the view
<%=link_to "Add", board_path(@board, topic_id: i.id), :method=> :put%>
Тем не менее, это все еще не входит в любое соглашение, так как вы не обновляете целую тему. Возможно, вы захотите использовать дополнительное действие, чтобы добавить тему на доску, используя глагол PATCH.